diff options
Diffstat (limited to 'arch/ppc/boot/lib')
-rw-r--r-- | arch/ppc/boot/lib/.gitignore | 3 | ||||
-rw-r--r-- | arch/ppc/boot/lib/Makefile | 23 | ||||
-rw-r--r-- | arch/ppc/boot/lib/div64.S | 58 | ||||
-rw-r--r-- | arch/ppc/boot/lib/kbd.c | 248 | ||||
-rw-r--r-- | arch/ppc/boot/lib/vreset.c | 805 |
5 files changed, 0 insertions, 1137 deletions
diff --git a/arch/ppc/boot/lib/.gitignore b/arch/ppc/boot/lib/.gitignore deleted file mode 100644 index 1629a6167755..000000000000 --- a/arch/ppc/boot/lib/.gitignore +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | inffast.c | ||
2 | inflate.c | ||
3 | inftrees.c | ||
diff --git a/arch/ppc/boot/lib/Makefile b/arch/ppc/boot/lib/Makefile deleted file mode 100644 index 2f995f712ec5..000000000000 --- a/arch/ppc/boot/lib/Makefile +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for some libs needed by zImage. | ||
3 | # | ||
4 | |||
5 | CFLAGS_kbd.o := -Idrivers/char | ||
6 | CFLAGS_vreset.o := -Iarch/ppc/boot/include | ||
7 | |||
8 | zlib := inffast.c inflate.c inftrees.c | ||
9 | |||
10 | lib-y += $(zlib:.c=.o) div64.o | ||
11 | lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o | ||
12 | |||
13 | |||
14 | # zlib files needs header from their original place | ||
15 | EXTRA_CFLAGS += -Ilib/zlib_inflate | ||
16 | |||
17 | quiet_cmd_copy_zlib = COPY $@ | ||
18 | cmd_copy_zlib = cat $< > $@ | ||
19 | |||
20 | $(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/% | ||
21 | $(call cmd,copy_zlib) | ||
22 | |||
23 | clean-files := $(zlib) | ||
diff --git a/arch/ppc/boot/lib/div64.S b/arch/ppc/boot/lib/div64.S deleted file mode 100644 index 3527569e9926..000000000000 --- a/arch/ppc/boot/lib/div64.S +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | /* | ||
2 | * Divide a 64-bit unsigned number by a 32-bit unsigned number. | ||
3 | * This routine assumes that the top 32 bits of the dividend are | ||
4 | * non-zero to start with. | ||
5 | * On entry, r3 points to the dividend, which get overwritten with | ||
6 | * the 64-bit quotient, and r4 contains the divisor. | ||
7 | * On exit, r3 contains the remainder. | ||
8 | * | ||
9 | * Copyright (C) 2002 Paul Mackerras, IBM Corp. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | #include <asm/ppc_asm.h> | ||
17 | #include <asm/processor.h> | ||
18 | |||
19 | _GLOBAL(__div64_32) | ||
20 | lwz r5,0(r3) # get the dividend into r5/r6 | ||
21 | lwz r6,4(r3) | ||
22 | cmplw r5,r4 | ||
23 | li r7,0 | ||
24 | li r8,0 | ||
25 | blt 1f | ||
26 | divwu r7,r5,r4 # if dividend.hi >= divisor, | ||
27 | mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor | ||
28 | subf. r5,r0,r5 # dividend.hi %= divisor | ||
29 | beq 3f | ||
30 | 1: mr r11,r5 # here dividend.hi != 0 | ||
31 | andis. r0,r5,0xc000 | ||
32 | bne 2f | ||
33 | cntlzw r0,r5 # we are shifting the dividend right | ||
34 | li r10,-1 # to make it < 2^32, and shifting | ||
35 | srw r10,r10,r0 # the divisor right the same amount, | ||
36 | add r9,r4,r10 # rounding up (so the estimate cannot | ||
37 | andc r11,r6,r10 # ever be too large, only too small) | ||
38 | andc r9,r9,r10 | ||
39 | or r11,r5,r11 | ||
40 | rotlw r9,r9,r0 | ||
41 | rotlw r11,r11,r0 | ||
42 | divwu r11,r11,r9 # then we divide the shifted quantities | ||
43 | 2: mullw r10,r11,r4 # to get an estimate of the quotient, | ||
44 | mulhwu r9,r11,r4 # multiply the estimate by the divisor, | ||
45 | subfc r6,r10,r6 # take the product from the divisor, | ||
46 | add r8,r8,r11 # and add the estimate to the accumulated | ||
47 | subfe. r5,r9,r5 # quotient | ||
48 | bne 1b | ||
49 | 3: cmplw r6,r4 | ||
50 | blt 4f | ||
51 | divwu r0,r6,r4 # perform the remaining 32-bit division | ||
52 | mullw r10,r0,r4 # and get the remainder | ||
53 | add r8,r8,r0 | ||
54 | subf r6,r10,r6 | ||
55 | 4: stw r7,0(r3) # return the quotient in *r3 | ||
56 | stw r8,4(r3) | ||
57 | mr r3,r6 # return the remainder in r3 | ||
58 | blr | ||
diff --git a/arch/ppc/boot/lib/kbd.c b/arch/ppc/boot/lib/kbd.c deleted file mode 100644 index 3931727434de..000000000000 --- a/arch/ppc/boot/lib/kbd.c +++ /dev/null | |||
@@ -1,248 +0,0 @@ | |||
1 | #include <linux/keyboard.h> | ||
2 | |||
3 | #include "defkeymap.c" /* yeah I know it's bad -- Cort */ | ||
4 | |||
5 | |||
6 | unsigned char shfts, ctls, alts, caps; | ||
7 | |||
8 | #define KBDATAP 0x60 /* kbd data port */ | ||
9 | #define KBSTATUSPORT 0x61 /* kbd status */ | ||
10 | #define KBSTATP 0x64 /* kbd status port */ | ||
11 | #define KBINRDY 0x01 | ||
12 | #define KBOUTRDY 0x02 | ||
13 | |||
14 | extern unsigned char inb(int port); | ||
15 | extern void outb(int port, char val); | ||
16 | extern void puts(const char *); | ||
17 | extern void puthex(unsigned long val); | ||
18 | extern void udelay(long x); | ||
19 | |||
20 | static int kbd(int noblock) | ||
21 | { | ||
22 | unsigned char dt, brk, val; | ||
23 | unsigned code; | ||
24 | loop: | ||
25 | if (noblock) { | ||
26 | if ((inb(KBSTATP) & KBINRDY) == 0) | ||
27 | return (-1); | ||
28 | } else while((inb(KBSTATP) & KBINRDY) == 0) ; | ||
29 | |||
30 | dt = inb(KBDATAP); | ||
31 | |||
32 | brk = dt & 0x80; /* brk == 1 on key release */ | ||
33 | dt = dt & 0x7f; /* keycode */ | ||
34 | |||
35 | if (shfts) | ||
36 | code = shift_map[dt]; | ||
37 | else if (ctls) | ||
38 | code = ctrl_map[dt]; | ||
39 | else | ||
40 | code = plain_map[dt]; | ||
41 | |||
42 | val = KVAL(code); | ||
43 | switch (KTYP(code) & 0x0f) { | ||
44 | case KT_LATIN: | ||
45 | if (brk) | ||
46 | break; | ||
47 | if (alts) | ||
48 | val |= 0x80; | ||
49 | if (val == 0x7f) /* map delete to backspace */ | ||
50 | val = '\b'; | ||
51 | return val; | ||
52 | |||
53 | case KT_LETTER: | ||
54 | if (brk) | ||
55 | break; | ||
56 | if (caps) | ||
57 | val -= 'a'-'A'; | ||
58 | return val; | ||
59 | |||
60 | case KT_SPEC: | ||
61 | if (brk) | ||
62 | break; | ||
63 | if (val == KVAL(K_CAPS)) | ||
64 | caps = !caps; | ||
65 | else if (val == KVAL(K_ENTER)) { | ||
66 | enter: /* Wait for key up */ | ||
67 | while (1) { | ||
68 | while((inb(KBSTATP) & KBINRDY) == 0) ; | ||
69 | dt = inb(KBDATAP); | ||
70 | if (dt & 0x80) /* key up */ break; | ||
71 | } | ||
72 | return 10; | ||
73 | } | ||
74 | break; | ||
75 | |||
76 | case KT_PAD: | ||
77 | if (brk) | ||
78 | break; | ||
79 | if (val < 10) | ||
80 | return val; | ||
81 | if (val == KVAL(K_PENTER)) | ||
82 | goto enter; | ||
83 | break; | ||
84 | |||
85 | case KT_SHIFT: | ||
86 | switch (val) { | ||
87 | case KG_SHIFT: | ||
88 | case KG_SHIFTL: | ||
89 | case KG_SHIFTR: | ||
90 | shfts = brk ? 0 : 1; | ||
91 | break; | ||
92 | case KG_ALT: | ||
93 | case KG_ALTGR: | ||
94 | alts = brk ? 0 : 1; | ||
95 | break; | ||
96 | case KG_CTRL: | ||
97 | case KG_CTRLL: | ||
98 | case KG_CTRLR: | ||
99 | ctls = brk ? 0 : 1; | ||
100 | break; | ||
101 | } | ||
102 | break; | ||
103 | |||
104 | case KT_LOCK: | ||
105 | switch (val) { | ||
106 | case KG_SHIFT: | ||
107 | case KG_SHIFTL: | ||
108 | case KG_SHIFTR: | ||
109 | if (brk) | ||
110 | shfts = !shfts; | ||
111 | break; | ||
112 | case KG_ALT: | ||
113 | case KG_ALTGR: | ||
114 | if (brk) | ||
115 | alts = !alts; | ||
116 | break; | ||
117 | case KG_CTRL: | ||
118 | case KG_CTRLL: | ||
119 | case KG_CTRLR: | ||
120 | if (brk) | ||
121 | ctls = !ctls; | ||
122 | break; | ||
123 | } | ||
124 | break; | ||
125 | } | ||
126 | if (brk) return (-1); /* Ignore initial 'key up' codes */ | ||
127 | goto loop; | ||
128 | } | ||
129 | |||
130 | static int __kbdreset(void) | ||
131 | { | ||
132 | unsigned char c; | ||
133 | int i, t; | ||
134 | |||
135 | /* flush input queue */ | ||
136 | t = 2000; | ||
137 | while ((inb(KBSTATP) & KBINRDY)) | ||
138 | { | ||
139 | (void)inb(KBDATAP); | ||
140 | if (--t == 0) | ||
141 | return 1; | ||
142 | } | ||
143 | /* Send self-test */ | ||
144 | t = 20000; | ||
145 | while (inb(KBSTATP) & KBOUTRDY) | ||
146 | if (--t == 0) | ||
147 | return 2; | ||
148 | outb(KBSTATP,0xAA); | ||
149 | t = 200000; | ||
150 | while ((inb(KBSTATP) & KBINRDY) == 0) /* wait input ready */ | ||
151 | if (--t == 0) | ||
152 | return 3; | ||
153 | if ((c = inb(KBDATAP)) != 0x55) | ||
154 | { | ||
155 | puts("Keyboard self test failed - result:"); | ||
156 | puthex(c); | ||
157 | puts("\n"); | ||
158 | } | ||
159 | /* Enable interrupts and keyboard controller */ | ||
160 | t = 20000; | ||
161 | while (inb(KBSTATP) & KBOUTRDY) | ||
162 | if (--t == 0) return 4; | ||
163 | outb(KBSTATP,0x60); | ||
164 | t = 20000; | ||
165 | while (inb(KBSTATP) & KBOUTRDY) | ||
166 | if (--t == 0) return 5; | ||
167 | outb(KBDATAP,0x45); | ||
168 | for (i = 0; i < 10000; i++) udelay(1); | ||
169 | |||
170 | t = 20000; | ||
171 | while (inb(KBSTATP) & KBOUTRDY) | ||
172 | if (--t == 0) return 6; | ||
173 | outb(KBSTATP,0x20); | ||
174 | t = 200000; | ||
175 | while ((inb(KBSTATP) & KBINRDY) == 0) /* wait input ready */ | ||
176 | if (--t == 0) return 7; | ||
177 | if (! (inb(KBDATAP) & 0x40)) { | ||
178 | /* | ||
179 | * Quote from PS/2 System Reference Manual: | ||
180 | * | ||
181 | * "Address hex 0060 and address hex 0064 should be | ||
182 | * written only when the input-buffer-full bit and | ||
183 | * output-buffer-full bit in the Controller Status | ||
184 | * register are set 0." (KBINRDY and KBOUTRDY) | ||
185 | */ | ||
186 | t = 200000; | ||
187 | while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) | ||
188 | if (--t == 0) return 8; | ||
189 | outb(KBDATAP,0xF0); | ||
190 | t = 200000; | ||
191 | while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) | ||
192 | if (--t == 0) return 9; | ||
193 | outb(KBDATAP,0x01); | ||
194 | } | ||
195 | t = 20000; | ||
196 | while (inb(KBSTATP) & KBOUTRDY) | ||
197 | if (--t == 0) return 10; | ||
198 | outb(KBSTATP,0xAE); | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static void kbdreset(void) | ||
203 | { | ||
204 | int ret = __kbdreset(); | ||
205 | |||
206 | if (ret) { | ||
207 | puts("__kbdreset failed: "); | ||
208 | puthex(ret); | ||
209 | puts("\n"); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | /* We have to actually read the keyboard when CRT_tstc is called, | ||
214 | * since the pending data might be a key release code, and therefore | ||
215 | * not valid data. In this case, kbd() will return -1, even though there's | ||
216 | * data to be read. Of course, we might actually read a valid key press, | ||
217 | * in which case it gets queued into key_pending for use by CRT_getc. | ||
218 | */ | ||
219 | |||
220 | static int kbd_reset = 0; | ||
221 | |||
222 | static int key_pending = -1; | ||
223 | |||
224 | int CRT_getc(void) | ||
225 | { | ||
226 | int c; | ||
227 | if (!kbd_reset) {kbdreset(); kbd_reset++; } | ||
228 | |||
229 | if (key_pending != -1) { | ||
230 | c = key_pending; | ||
231 | key_pending = -1; | ||
232 | return c; | ||
233 | } else { | ||
234 | while ((c = kbd(0)) == 0) ; | ||
235 | return c; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | int CRT_tstc(void) | ||
240 | { | ||
241 | if (!kbd_reset) {kbdreset(); kbd_reset++; } | ||
242 | |||
243 | while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) { | ||
244 | key_pending = kbd(1); | ||
245 | } | ||
246 | |||
247 | return (key_pending != -1); | ||
248 | } | ||
diff --git a/arch/ppc/boot/lib/vreset.c b/arch/ppc/boot/lib/vreset.c deleted file mode 100644 index 98539e9f7f96..000000000000 --- a/arch/ppc/boot/lib/vreset.c +++ /dev/null | |||
@@ -1,805 +0,0 @@ | |||
1 | /* | ||
2 | * vreset.c | ||
3 | * | ||
4 | * Initialize the VGA control registers to 80x25 text mode. | ||
5 | * | ||
6 | * Adapted from a program by: | ||
7 | * Steve Sellgren | ||
8 | * San Francisco Indigo Company | ||
9 | * sfindigo!sellgren@uunet.uu.net | ||
10 | * | ||
11 | * Original concept by: | ||
12 | * Gary Thomas <gdt@linuxppc.org> | ||
13 | * Adapted for Moto boxes by: | ||
14 | * Pat Kane & Mark Scott, 1996 | ||
15 | * Adapted for IBM portables by: | ||
16 | * Takeshi Ishimoto | ||
17 | * Multi-console support: | ||
18 | * Terje Malmedal <terje.malmedal@usit.uio.no> | ||
19 | */ | ||
20 | |||
21 | #include "iso_font.h" | ||
22 | #include "nonstdio.h" | ||
23 | |||
24 | extern char *vidmem; | ||
25 | extern int lines, cols; | ||
26 | struct VaRegs; | ||
27 | |||
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 | |||
38 | void unlockVideo(int slot); | ||
39 | void setTextRegs(struct VgaRegs *svp); | ||
40 | void setTextCLUT(int shift); | ||
41 | void clearVideoMemory(void); | ||
42 | void loadFont(unsigned char *ISA_mem); | ||
43 | |||
44 | static void mdelay(int ms) | ||
45 | { | ||
46 | for (; ms > 0; --ms) | ||
47 | udelay(1000); | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * Default console text mode registers used to reset | ||
52 | * graphics adapter. | ||
53 | */ | ||
54 | #define NREGS 54 | ||
55 | #define ENDMK 0xFFFF /* End marker */ | ||
56 | |||
57 | #define S3Vendor 0x5333 | ||
58 | #define CirrusVendor 0x1013 | ||
59 | #define DiamondVendor 0x100E | ||
60 | #define MatroxVendor 0x102B | ||
61 | #define ParadiseVendor 0x101C | ||
62 | |||
63 | struct VgaRegs GenVgaTextRegs[NREGS+1] = { | ||
64 | /* port index value */ | ||
65 | /* SR Regs */ | ||
66 | { 0x3c4, 0x1, 0x0 }, | ||
67 | { 0x3c4, 0x2, 0x3 }, | ||
68 | { 0x3c4, 0x3, 0x0 }, | ||
69 | { 0x3c4, 0x4, 0x2 }, | ||
70 | /* CR Regs */ | ||
71 | { 0x3d4, 0x0, 0x5f }, | ||
72 | { 0x3d4, 0x1, 0x4f }, | ||
73 | { 0x3d4, 0x2, 0x50 }, | ||
74 | { 0x3d4, 0x3, 0x82 }, | ||
75 | { 0x3d4, 0x4, 0x55 }, | ||
76 | { 0x3d4, 0x5, 0x81 }, | ||
77 | { 0x3d4, 0x6, 0xbf }, | ||
78 | { 0x3d4, 0x7, 0x1f }, | ||
79 | { 0x3d4, 0x8, 0x00 }, | ||
80 | { 0x3d4, 0x9, 0x4f }, | ||
81 | { 0x3d4, 0xa, 0x0d }, | ||
82 | { 0x3d4, 0xb, 0x0e }, | ||
83 | { 0x3d4, 0xc, 0x00 }, | ||
84 | { 0x3d4, 0xd, 0x00 }, | ||
85 | { 0x3d4, 0xe, 0x00 }, | ||
86 | { 0x3d4, 0xf, 0x00 }, | ||
87 | { 0x3d4, 0x10, 0x9c }, | ||
88 | { 0x3d4, 0x11, 0x8e }, | ||
89 | { 0x3d4, 0x12, 0x8f }, | ||
90 | { 0x3d4, 0x13, 0x28 }, | ||
91 | { 0x3d4, 0x14, 0x1f }, | ||
92 | { 0x3d4, 0x15, 0x96 }, | ||
93 | { 0x3d4, 0x16, 0xb9 }, | ||
94 | { 0x3d4, 0x17, 0xa3 }, | ||
95 | /* GR Regs */ | ||
96 | { 0x3ce, 0x0, 0x0 }, | ||
97 | { 0x3ce, 0x1, 0x0 }, | ||
98 | { 0x3ce, 0x2, 0x0 }, | ||
99 | { 0x3ce, 0x3, 0x0 }, | ||
100 | { 0x3ce, 0x4, 0x0 }, | ||
101 | { 0x3ce, 0x5, 0x10 }, | ||
102 | { 0x3ce, 0x6, 0xe }, | ||
103 | { 0x3ce, 0x7, 0x0 }, | ||
104 | { 0x3ce, 0x8, 0xff }, | ||
105 | { ENDMK } | ||
106 | }; | ||
107 | |||
108 | struct RGBColors | ||
109 | { | ||
110 | unsigned char r, g, b; | ||
111 | }; | ||
112 | |||
113 | /* | ||
114 | * Default console text mode color table. | ||
115 | * These values were obtained by booting Linux with | ||
116 | * text mode firmware & then dumping the registers. | ||
117 | */ | ||
118 | struct RGBColors TextCLUT[256] = | ||
119 | { | ||
120 | /* red green blue */ | ||
121 | { 0x0, 0x0, 0x0 }, | ||
122 | { 0x0, 0x0, 0x2a }, | ||
123 | { 0x0, 0x2a, 0x0 }, | ||
124 | { 0x0, 0x2a, 0x2a }, | ||
125 | { 0x2a, 0x0, 0x0 }, | ||
126 | { 0x2a, 0x0, 0x2a }, | ||
127 | { 0x2a, 0x2a, 0x0 }, | ||
128 | { 0x2a, 0x2a, 0x2a }, | ||
129 | { 0x0, 0x0, 0x15 }, | ||
130 | { 0x0, 0x0, 0x3f }, | ||
131 | { 0x0, 0x2a, 0x15 }, | ||
132 | { 0x0, 0x2a, 0x3f }, | ||
133 | { 0x2a, 0x0, 0x15 }, | ||
134 | { 0x2a, 0x0, 0x3f }, | ||
135 | { 0x2a, 0x2a, 0x15 }, | ||
136 | { 0x2a, 0x2a, 0x3f }, | ||
137 | { 0x0, 0x15, 0x0 }, | ||
138 | { 0x0, 0x15, 0x2a }, | ||
139 | { 0x0, 0x3f, 0x0 }, | ||
140 | { 0x0, 0x3f, 0x2a }, | ||
141 | { 0x2a, 0x15, 0x0 }, | ||
142 | { 0x2a, 0x15, 0x2a }, | ||
143 | { 0x2a, 0x3f, 0x0 }, | ||
144 | { 0x2a, 0x3f, 0x2a }, | ||
145 | { 0x0, 0x15, 0x15 }, | ||
146 | { 0x0, 0x15, 0x3f }, | ||
147 | { 0x0, 0x3f, 0x15 }, | ||
148 | { 0x0, 0x3f, 0x3f }, | ||
149 | { 0x2a, 0x15, 0x15 }, | ||
150 | { 0x2a, 0x15, 0x3f }, | ||
151 | { 0x2a, 0x3f, 0x15 }, | ||
152 | { 0x2a, 0x3f, 0x3f }, | ||
153 | { 0x15, 0x0, 0x0 }, | ||
154 | { 0x15, 0x0, 0x2a }, | ||
155 | { 0x15, 0x2a, 0x0 }, | ||
156 | { 0x15, 0x2a, 0x2a }, | ||
157 | { 0x3f, 0x0, 0x0 }, | ||
158 | { 0x3f, 0x0, 0x2a }, | ||
159 | { 0x3f, 0x2a, 0x0 }, | ||
160 | { 0x3f, 0x2a, 0x2a }, | ||
161 | { 0x15, 0x0, 0x15 }, | ||
162 | { 0x15, 0x0, 0x3f }, | ||
163 | { 0x15, 0x2a, 0x15 }, | ||
164 | { 0x15, 0x2a, 0x3f }, | ||
165 | { 0x3f, 0x0, 0x15 }, | ||
166 | { 0x3f, 0x0, 0x3f }, | ||
167 | { 0x3f, 0x2a, 0x15 }, | ||
168 | { 0x3f, 0x2a, 0x3f }, | ||
169 | { 0x15, 0x15, 0x0 }, | ||
170 | { 0x15, 0x15, 0x2a }, | ||
171 | { 0x15, 0x3f, 0x0 }, | ||
172 | { 0x15, 0x3f, 0x2a }, | ||
173 | { 0x3f, 0x15, 0x0 }, | ||
174 | { 0x3f, 0x15, 0x2a }, | ||
175 | { 0x3f, 0x3f, 0x0 }, | ||
176 | { 0x3f, 0x3f, 0x2a }, | ||
177 | { 0x15, 0x15, 0x15 }, | ||
178 | { 0x15, 0x15, 0x3f }, | ||
179 | { 0x15, 0x3f, 0x15 }, | ||
180 | { 0x15, 0x3f, 0x3f }, | ||
181 | { 0x3f, 0x15, 0x15 }, | ||
182 | { 0x3f, 0x15, 0x3f }, | ||
183 | { 0x3f, 0x3f, 0x15 }, | ||
184 | { 0x3f, 0x3f, 0x3f }, | ||
185 | { 0x39, 0xc, 0x5 }, | ||
186 | { 0x15, 0x2c, 0xf }, | ||
187 | { 0x26, 0x10, 0x3d }, | ||
188 | { 0x29, 0x29, 0x38 }, | ||
189 | { 0x4, 0x1a, 0xe }, | ||
190 | { 0x2, 0x1e, 0x3a }, | ||
191 | { 0x3c, 0x25, 0x33 }, | ||
192 | { 0x3c, 0xc, 0x2c }, | ||
193 | { 0x3f, 0x3, 0x2b }, | ||
194 | { 0x1c, 0x9, 0x13 }, | ||
195 | { 0x25, 0x2a, 0x35 }, | ||
196 | { 0x1e, 0xa, 0x38 }, | ||
197 | { 0x24, 0x8, 0x3 }, | ||
198 | { 0x3, 0xe, 0x36 }, | ||
199 | { 0xc, 0x6, 0x2a }, | ||
200 | { 0x26, 0x3, 0x32 }, | ||
201 | { 0x5, 0x2f, 0x33 }, | ||
202 | { 0x3c, 0x35, 0x2f }, | ||
203 | { 0x2d, 0x26, 0x3e }, | ||
204 | { 0xd, 0xa, 0x10 }, | ||
205 | { 0x25, 0x3c, 0x11 }, | ||
206 | { 0xd, 0x4, 0x2e }, | ||
207 | { 0x5, 0x19, 0x3e }, | ||
208 | { 0xc, 0x13, 0x34 }, | ||
209 | { 0x2b, 0x6, 0x24 }, | ||
210 | { 0x4, 0x3, 0xd }, | ||
211 | { 0x2f, 0x3c, 0xc }, | ||
212 | { 0x2a, 0x37, 0x1f }, | ||
213 | { 0xf, 0x12, 0x38 }, | ||
214 | { 0x38, 0xe, 0x2a }, | ||
215 | { 0x12, 0x2f, 0x19 }, | ||
216 | { 0x29, 0x2e, 0x31 }, | ||
217 | { 0x25, 0x13, 0x3e }, | ||
218 | { 0x33, 0x3e, 0x33 }, | ||
219 | { 0x1d, 0x2c, 0x25 }, | ||
220 | { 0x15, 0x15, 0x5 }, | ||
221 | { 0x32, 0x25, 0x39 }, | ||
222 | { 0x1a, 0x7, 0x1f }, | ||
223 | { 0x13, 0xe, 0x1d }, | ||
224 | { 0x36, 0x17, 0x34 }, | ||
225 | { 0xf, 0x15, 0x23 }, | ||
226 | { 0x2, 0x35, 0xd }, | ||
227 | { 0x15, 0x3f, 0xc }, | ||
228 | { 0x14, 0x2f, 0xf }, | ||
229 | { 0x19, 0x21, 0x3e }, | ||
230 | { 0x27, 0x11, 0x2f }, | ||
231 | { 0x38, 0x3f, 0x3c }, | ||
232 | { 0x36, 0x2d, 0x15 }, | ||
233 | { 0x16, 0x17, 0x2 }, | ||
234 | { 0x1, 0xa, 0x3d }, | ||
235 | { 0x1b, 0x11, 0x3f }, | ||
236 | { 0x21, 0x3c, 0xd }, | ||
237 | { 0x1a, 0x39, 0x3d }, | ||
238 | { 0x8, 0xe, 0xe }, | ||
239 | { 0x22, 0x21, 0x23 }, | ||
240 | { 0x1e, 0x30, 0x5 }, | ||
241 | { 0x1f, 0x22, 0x3d }, | ||
242 | { 0x1e, 0x2f, 0xa }, | ||
243 | { 0x0, 0x1c, 0xe }, | ||
244 | { 0x0, 0x1c, 0x15 }, | ||
245 | { 0x0, 0x1c, 0x1c }, | ||
246 | { 0x0, 0x15, 0x1c }, | ||
247 | { 0x0, 0xe, 0x1c }, | ||
248 | { 0x0, 0x7, 0x1c }, | ||
249 | { 0xe, 0xe, 0x1c }, | ||
250 | { 0x11, 0xe, 0x1c }, | ||
251 | { 0x15, 0xe, 0x1c }, | ||
252 | { 0x18, 0xe, 0x1c }, | ||
253 | { 0x1c, 0xe, 0x1c }, | ||
254 | { 0x1c, 0xe, 0x18 }, | ||
255 | { 0x1c, 0xe, 0x15 }, | ||
256 | { 0x1c, 0xe, 0x11 }, | ||
257 | { 0x1c, 0xe, 0xe }, | ||
258 | { 0x1c, 0x11, 0xe }, | ||
259 | { 0x1c, 0x15, 0xe }, | ||
260 | { 0x1c, 0x18, 0xe }, | ||
261 | { 0x1c, 0x1c, 0xe }, | ||
262 | { 0x18, 0x1c, 0xe }, | ||
263 | { 0x15, 0x1c, 0xe }, | ||
264 | { 0x11, 0x1c, 0xe }, | ||
265 | { 0xe, 0x1c, 0xe }, | ||
266 | { 0xe, 0x1c, 0x11 }, | ||
267 | { 0xe, 0x1c, 0x15 }, | ||
268 | { 0xe, 0x1c, 0x18 }, | ||
269 | { 0xe, 0x1c, 0x1c }, | ||
270 | { 0xe, 0x18, 0x1c }, | ||
271 | { 0xe, 0x15, 0x1c }, | ||
272 | { 0xe, 0x11, 0x1c }, | ||
273 | { 0x14, 0x14, 0x1c }, | ||
274 | { 0x16, 0x14, 0x1c }, | ||
275 | { 0x18, 0x14, 0x1c }, | ||
276 | { 0x1a, 0x14, 0x1c }, | ||
277 | { 0x1c, 0x14, 0x1c }, | ||
278 | { 0x1c, 0x14, 0x1a }, | ||
279 | { 0x1c, 0x14, 0x18 }, | ||
280 | { 0x1c, 0x14, 0x16 }, | ||
281 | { 0x1c, 0x14, 0x14 }, | ||
282 | { 0x1c, 0x16, 0x14 }, | ||
283 | { 0x1c, 0x18, 0x14 }, | ||
284 | { 0x1c, 0x1a, 0x14 }, | ||
285 | { 0x1c, 0x1c, 0x14 }, | ||
286 | { 0x1a, 0x1c, 0x14 }, | ||
287 | { 0x18, 0x1c, 0x14 }, | ||
288 | { 0x16, 0x1c, 0x14 }, | ||
289 | { 0x14, 0x1c, 0x14 }, | ||
290 | { 0x14, 0x1c, 0x16 }, | ||
291 | { 0x14, 0x1c, 0x18 }, | ||
292 | { 0x14, 0x1c, 0x1a }, | ||
293 | { 0x14, 0x1c, 0x1c }, | ||
294 | { 0x14, 0x1a, 0x1c }, | ||
295 | { 0x14, 0x18, 0x1c }, | ||
296 | { 0x14, 0x16, 0x1c }, | ||
297 | { 0x0, 0x0, 0x10 }, | ||
298 | { 0x4, 0x0, 0x10 }, | ||
299 | { 0x8, 0x0, 0x10 }, | ||
300 | { 0xc, 0x0, 0x10 }, | ||
301 | { 0x10, 0x0, 0x10 }, | ||
302 | { 0x10, 0x0, 0xc }, | ||
303 | { 0x10, 0x0, 0x8 }, | ||
304 | { 0x10, 0x0, 0x4 }, | ||
305 | { 0x10, 0x0, 0x0 }, | ||
306 | { 0x10, 0x4, 0x0 }, | ||
307 | { 0x10, 0x8, 0x0 }, | ||
308 | { 0x10, 0xc, 0x0 }, | ||
309 | { 0x10, 0x10, 0x0 }, | ||
310 | { 0xc, 0x10, 0x0 }, | ||
311 | { 0x8, 0x10, 0x0 }, | ||
312 | { 0x4, 0x10, 0x0 }, | ||
313 | { 0x0, 0x10, 0x0 }, | ||
314 | { 0x0, 0x10, 0x4 }, | ||
315 | { 0x0, 0x10, 0x8 }, | ||
316 | { 0x0, 0x10, 0xc }, | ||
317 | { 0x0, 0x10, 0x10 }, | ||
318 | { 0x0, 0xc, 0x10 }, | ||
319 | { 0x0, 0x8, 0x10 }, | ||
320 | { 0x0, 0x4, 0x10 }, | ||
321 | { 0x8, 0x8, 0x10 }, | ||
322 | { 0xa, 0x8, 0x10 }, | ||
323 | { 0xc, 0x8, 0x10 }, | ||
324 | { 0xe, 0x8, 0x10 }, | ||
325 | { 0x10, 0x8, 0x10 }, | ||
326 | { 0x10, 0x8, 0xe }, | ||
327 | { 0x10, 0x8, 0xc }, | ||
328 | { 0x10, 0x8, 0xa }, | ||
329 | { 0x10, 0x8, 0x8 }, | ||
330 | { 0x10, 0xa, 0x8 }, | ||
331 | { 0x10, 0xc, 0x8 }, | ||
332 | { 0x10, 0xe, 0x8 }, | ||
333 | { 0x10, 0x10, 0x8 }, | ||
334 | { 0xe, 0x10, 0x8 }, | ||
335 | { 0xc, 0x10, 0x8 }, | ||
336 | { 0xa, 0x10, 0x8 }, | ||
337 | { 0x8, 0x10, 0x8 }, | ||
338 | { 0x8, 0x10, 0xa }, | ||
339 | { 0x8, 0x10, 0xc }, | ||
340 | { 0x8, 0x10, 0xe }, | ||
341 | { 0x8, 0x10, 0x10 }, | ||
342 | { 0x8, 0xe, 0x10 }, | ||
343 | { 0x8, 0xc, 0x10 }, | ||
344 | { 0x8, 0xa, 0x10 }, | ||
345 | { 0xb, 0xb, 0x10 }, | ||
346 | { 0xc, 0xb, 0x10 }, | ||
347 | { 0xd, 0xb, 0x10 }, | ||
348 | { 0xf, 0xb, 0x10 }, | ||
349 | { 0x10, 0xb, 0x10 }, | ||
350 | { 0x10, 0xb, 0xf }, | ||
351 | { 0x10, 0xb, 0xd }, | ||
352 | { 0x10, 0xb, 0xc }, | ||
353 | { 0x10, 0xb, 0xb }, | ||
354 | { 0x10, 0xc, 0xb }, | ||
355 | { 0x10, 0xd, 0xb }, | ||
356 | { 0x10, 0xf, 0xb }, | ||
357 | { 0x10, 0x10, 0xb }, | ||
358 | { 0xf, 0x10, 0xb }, | ||
359 | { 0xd, 0x10, 0xb }, | ||
360 | { 0xc, 0x10, 0xb }, | ||
361 | { 0xb, 0x10, 0xb }, | ||
362 | { 0xb, 0x10, 0xc }, | ||
363 | { 0xb, 0x10, 0xd }, | ||
364 | { 0xb, 0x10, 0xf }, | ||
365 | { 0xb, 0x10, 0x10 }, | ||
366 | { 0xb, 0xf, 0x10 }, | ||
367 | { 0xb, 0xd, 0x10 }, | ||
368 | { 0xb, 0xc, 0x10 }, | ||
369 | { 0x0, 0x0, 0x0 }, | ||
370 | { 0x0, 0x0, 0x0 }, | ||
371 | { 0x0, 0x0, 0x0 }, | ||
372 | { 0x0, 0x0, 0x0 }, | ||
373 | { 0x0, 0x0, 0x0 }, | ||
374 | { 0x0, 0x0, 0x0 }, | ||
375 | { 0x0, 0x0, 0x0 } | ||
376 | }; | ||
377 | |||
378 | unsigned char AC[21] = { | ||
379 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, | ||
380 | 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, | ||
381 | 0x0C, 0x00, 0x0F, 0x08, 0x00}; | ||
382 | |||
383 | static int scanPCI(int start_slt); | ||
384 | static int PCIVendor(int); | ||
385 | #ifdef DEBUG | ||
386 | static void printslots(void); | ||
387 | #endif | ||
388 | extern void puthex(unsigned long); | ||
389 | extern void puts(const char *); | ||
390 | static void unlockS3(void); | ||
391 | |||
392 | static inline void | ||
393 | outw(int port, unsigned short val) | ||
394 | { | ||
395 | outb(port, val >> 8); | ||
396 | outb(port+1, val); | ||
397 | } | ||
398 | |||
399 | int | ||
400 | vga_init(unsigned char *ISA_mem) | ||
401 | { | ||
402 | int slot; | ||
403 | struct VgaRegs *VgaTextRegs; | ||
404 | |||
405 | /* See if VGA already in TEXT mode - exit if so! */ | ||
406 | outb(0x3CE, 0x06); | ||
407 | if ((inb(0x3CF) & 0x01) == 0){ | ||
408 | puts("VGA already in text mode\n"); | ||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | /* If no VGA responding in text mode, then we have some work to do... | ||
413 | */ | ||
414 | slot = -1; | ||
415 | while((slot = scanPCI(slot)) > -1) { /* find video card in use */ | ||
416 | unlockVideo(slot); /* enable I/O to card */ | ||
417 | VgaTextRegs = GenVgaTextRegs; | ||
418 | |||
419 | switch (PCIVendor(slot)) { | ||
420 | default: | ||
421 | break; | ||
422 | case(S3Vendor): | ||
423 | unlockS3(); | ||
424 | break; | ||
425 | |||
426 | case(CirrusVendor): | ||
427 | outw(0x3C4, 0x0612); /* unlock ext regs */ | ||
428 | outw(0x3C4, 0x0700); /* reset ext sequence mode */ | ||
429 | break; | ||
430 | |||
431 | case(ParadiseVendor): /* IBM Portable 850 */ | ||
432 | outw(0x3ce, 0x0f05); /* unlock pardise registers */ | ||
433 | outw(0x3c4, 0x0648); | ||
434 | outw(0x3d4, 0x2985); | ||
435 | outw(0x3d4, 0x34a6); | ||
436 | outb(0x3ce, 0x0b); /* disable linear addressing */ | ||
437 | outb(0x3cf, inb(0x3cf) & ~0x30); | ||
438 | outw(0x3c4, 0x1400); | ||
439 | outb(0x3ce, 0x0e); /* disable 256 color mode */ | ||
440 | outb(0x3cf, inb(0x3cf) & ~0x01); | ||
441 | outb(0xd00, 0xff); /* enable auto-centering */ | ||
442 | if (!(inb(0xd01) & 0x03)) { | ||
443 | outb(0x3d4, 0x33); | ||
444 | outb(0x3d5, inb(0x3d5) & ~0x90); | ||
445 | outb(0x3d4, 0x32); | ||
446 | outb(0x3d5, inb(0x3d5) | 0x04); | ||
447 | outw(0x3d4, 0x0250); | ||
448 | outw(0x3d4, 0x07ba); | ||
449 | outw(0x3d4, 0x0900); | ||
450 | outw(0x3d4, 0x15e7); | ||
451 | outw(0x3d4, 0x2a95); | ||
452 | } | ||
453 | outw(0x3d4, 0x34a0); | ||
454 | break; | ||
455 | |||
456 | #if 0 /* Untested - probably doesn't work */ | ||
457 | case(MatroxVendor): | ||
458 | case(DiamondVendor): | ||
459 | puts("VGA Chip Vendor ID: "); | ||
460 | puthex(PCIVendor(slot)); | ||
461 | puts("\n"); | ||
462 | mdelay(1000); | ||
463 | #endif | ||
464 | }; | ||
465 | |||
466 | outw(0x3C4, 0x0120); /* disable video */ | ||
467 | setTextRegs(VgaTextRegs); /* initial register setup */ | ||
468 | setTextCLUT(0); /* load color lookup table */ | ||
469 | loadFont(ISA_mem); /* load font */ | ||
470 | setTextRegs(VgaTextRegs); /* reload registers */ | ||
471 | outw(0x3C4, 0x0100); /* re-enable video */ | ||
472 | clearVideoMemory(); | ||
473 | |||
474 | if (PCIVendor(slot) == S3Vendor) { | ||
475 | outb(0x3c2, 0x63); /* MISC */ | ||
476 | } /* endif */ | ||
477 | |||
478 | #ifdef DEBUG | ||
479 | printslots(); | ||
480 | mdelay(5000); | ||
481 | #endif | ||
482 | |||
483 | mdelay(1000); /* give time for the video monitor to come up */ | ||
484 | } | ||
485 | return (1); /* 'CRT' I/O supported */ | ||
486 | } | ||
487 | |||
488 | /* | ||
489 | * Write to VGA Attribute registers. | ||
490 | */ | ||
491 | void | ||
492 | writeAttr(unsigned char index, unsigned char data, unsigned char videoOn) | ||
493 | { | ||
494 | unsigned char v; | ||
495 | v = inb(0x3da); /* reset attr. address toggle */ | ||
496 | if (videoOn) | ||
497 | outb(0x3c0, (index & 0x1F) | 0x20); | ||
498 | else | ||
499 | outb(0x3c0, (index & 0x1F)); | ||
500 | outb(0x3c0, data); | ||
501 | } | ||
502 | |||
503 | void | ||
504 | setTextRegs(struct VgaRegs *svp) | ||
505 | { | ||
506 | int i; | ||
507 | |||
508 | /* | ||
509 | * saved settings | ||
510 | */ | ||
511 | while( svp->io_port != ENDMK ) { | ||
512 | outb(svp->io_port, svp->io_index); | ||
513 | outb(svp->io_port+1, svp->io_value); | ||
514 | svp++; | ||
515 | } | ||
516 | |||
517 | outb(0x3c2, 0x67); /* MISC */ | ||
518 | outb(0x3c6, 0xff); /* MASK */ | ||
519 | |||
520 | for ( i = 0; i < 0x10; i++) | ||
521 | writeAttr(i, AC[i], 0); /* palette */ | ||
522 | writeAttr(0x10, 0x0c, 0); /* text mode */ | ||
523 | writeAttr(0x11, 0x00, 0); /* overscan color (border) */ | ||
524 | writeAttr(0x12, 0x0f, 0); /* plane enable */ | ||
525 | writeAttr(0x13, 0x08, 0); /* pixel panning */ | ||
526 | writeAttr(0x14, 0x00, 1); /* color select; video on */ | ||
527 | } | ||
528 | |||
529 | void | ||
530 | setTextCLUT(int shift) | ||
531 | { | ||
532 | int i; | ||
533 | |||
534 | outb(0x3C6, 0xFF); | ||
535 | i = inb(0x3C7); | ||
536 | outb(0x3C8, 0); | ||
537 | i = inb(0x3C7); | ||
538 | |||
539 | for ( i = 0; i < 256; i++) { | ||
540 | outb(0x3C9, TextCLUT[i].r << shift); | ||
541 | outb(0x3C9, TextCLUT[i].g << shift); | ||
542 | outb(0x3C9, TextCLUT[i].b << shift); | ||
543 | } | ||
544 | } | ||
545 | |||
546 | void | ||
547 | loadFont(unsigned char *ISA_mem) | ||
548 | { | ||
549 | int i, j; | ||
550 | unsigned char *font_page = (unsigned char *) &ISA_mem[0xA0000]; | ||
551 | |||
552 | outb(0x3C2, 0x67); | ||
553 | /* | ||
554 | * Load font | ||
555 | */ | ||
556 | i = inb(0x3DA); /* Reset Attr toggle */ | ||
557 | |||
558 | outb(0x3C0,0x30); | ||
559 | outb(0x3C0, 0x01); /* graphics mode */ | ||
560 | |||
561 | outw(0x3C4, 0x0001); /* reset sequencer */ | ||
562 | outw(0x3C4, 0x0204); /* write to plane 2 */ | ||
563 | outw(0x3C4, 0x0406); /* enable plane graphics */ | ||
564 | outw(0x3C4, 0x0003); /* reset sequencer */ | ||
565 | outw(0x3CE, 0x0402); /* read plane 2 */ | ||
566 | outw(0x3CE, 0x0500); /* write mode 0, read mode 0 */ | ||
567 | outw(0x3CE, 0x0605); /* set graphics mode */ | ||
568 | |||
569 | for (i = 0; i < sizeof(font); i += 16) { | ||
570 | for (j = 0; j < 16; j++) { | ||
571 | __asm__ volatile("eieio"); | ||
572 | font_page[(2*i)+j] = font[i+j]; | ||
573 | } | ||
574 | } | ||
575 | } | ||
576 | |||
577 | static void | ||
578 | unlockS3(void) | ||
579 | { | ||
580 | int s3_device_id; | ||
581 | outw(0x3d4, 0x3848); | ||
582 | outw(0x3d4, 0x39a5); | ||
583 | outb(0x3d4, 0x2d); | ||
584 | s3_device_id = inb(0x3d5) << 8; | ||
585 | outb(0x3d4, 0x2e); | ||
586 | s3_device_id |= inb(0x3d5); | ||
587 | |||
588 | if (s3_device_id != 0x8812) { | ||
589 | /* From the S3 manual */ | ||
590 | outb(0x46E8, 0x10); /* Put into setup mode */ | ||
591 | outb(0x3C3, 0x10); | ||
592 | outb(0x102, 0x01); /* Enable registers */ | ||
593 | outb(0x46E8, 0x08); /* Enable video */ | ||
594 | outb(0x3C3, 0x08); | ||
595 | outb(0x4AE8, 0x00); | ||
596 | |||
597 | #if 0 | ||
598 | outb(0x42E8, 0x80); /* Reset graphics engine? */ | ||
599 | #endif | ||
600 | |||
601 | outb(0x3D4, 0x38); /* Unlock all registers */ | ||
602 | outb(0x3D5, 0x48); | ||
603 | outb(0x3D4, 0x39); | ||
604 | outb(0x3D5, 0xA5); | ||
605 | outb(0x3D4, 0x40); | ||
606 | outb(0x3D5, inb(0x3D5)|0x01); | ||
607 | outb(0x3D4, 0x33); | ||
608 | outb(0x3D5, inb(0x3D5)&~0x52); | ||
609 | outb(0x3D4, 0x35); | ||
610 | outb(0x3D5, inb(0x3D5)&~0x30); | ||
611 | outb(0x3D4, 0x3A); | ||
612 | outb(0x3D5, 0x00); | ||
613 | outb(0x3D4, 0x53); | ||
614 | outb(0x3D5, 0x00); | ||
615 | outb(0x3D4, 0x31); | ||
616 | outb(0x3D5, inb(0x3D5)&~0x4B); | ||
617 | outb(0x3D4, 0x58); | ||
618 | |||
619 | outb(0x3D5, 0); | ||
620 | |||
621 | outb(0x3D4, 0x54); | ||
622 | outb(0x3D5, 0x38); | ||
623 | outb(0x3D4, 0x60); | ||
624 | outb(0x3D5, 0x07); | ||
625 | outb(0x3D4, 0x61); | ||
626 | outb(0x3D5, 0x80); | ||
627 | outb(0x3D4, 0x62); | ||
628 | outb(0x3D5, 0xA1); | ||
629 | outb(0x3D4, 0x69); /* High order bits for cursor address */ | ||
630 | outb(0x3D5, 0); | ||
631 | |||
632 | outb(0x3D4, 0x32); | ||
633 | outb(0x3D5, inb(0x3D5)&~0x10); | ||
634 | } else { | ||
635 | outw(0x3c4, 0x0806); /* IBM Portable 860 */ | ||
636 | outw(0x3c4, 0x1041); | ||
637 | outw(0x3c4, 0x1128); | ||
638 | outw(0x3d4, 0x4000); | ||
639 | outw(0x3d4, 0x3100); | ||
640 | outw(0x3d4, 0x3a05); | ||
641 | outw(0x3d4, 0x6688); | ||
642 | outw(0x3d4, 0x5800); /* disable linear addressing */ | ||
643 | outw(0x3d4, 0x4500); /* disable H/W cursor */ | ||
644 | outw(0x3c4, 0x5410); /* enable auto-centering */ | ||
645 | outw(0x3c4, 0x561f); | ||
646 | outw(0x3c4, 0x1b80); /* lock DCLK selection */ | ||
647 | outw(0x3d4, 0x3900); /* lock S3 registers */ | ||
648 | outw(0x3d4, 0x3800); | ||
649 | } /* endif */ | ||
650 | } | ||
651 | |||
652 | /* | ||
653 | * cursor() sets an offset (0-1999) into the 80x25 text area. | ||
654 | */ | ||
655 | void | ||
656 | cursor(int x, int y) | ||
657 | { | ||
658 | int pos = (y*cols)+x; | ||
659 | outb(0x3D4, 14); | ||
660 | outb(0x3D5, pos >> 8); | ||
661 | outb(0x3D4, 15); | ||
662 | outb(0x3D5, pos); | ||
663 | } | ||
664 | |||
665 | void | ||
666 | clearVideoMemory(void) | ||
667 | { | ||
668 | int i, j; | ||
669 | for (i = 0; i < lines; i++) { | ||
670 | for (j = 0; j < cols; j++) { | ||
671 | vidmem[((i*cols)+j)*2] = 0x20; /* fill with space character */ | ||
672 | vidmem[((i*cols)+j)*2+1] = 0x07; /* set bg & fg attributes */ | ||
673 | } | ||
674 | } | ||
675 | } | ||
676 | |||
677 | /* ============ */ | ||
678 | |||
679 | |||
680 | #define NSLOTS 8 | ||
681 | #define NPCIREGS 5 | ||
682 | |||
683 | |||
684 | /* | ||
685 | should use devfunc number/indirect method to be totally safe on | ||
686 | all machines, this works for now on 3 slot Moto boxes | ||
687 | */ | ||
688 | |||
689 | struct PCI_ConfigInfo { | ||
690 | unsigned long * config_addr; | ||
691 | unsigned long regs[NPCIREGS]; | ||
692 | } PCI_slots [NSLOTS] = { | ||
693 | |||
694 | { (unsigned long *)0x80808000, {0xDEADBEEF,} }, /* onboard */ | ||
695 | { (unsigned long *)0x80800800, {0xDEADBEEF,} }, /* onboard */ | ||
696 | { (unsigned long *)0x80801000, {0xDEADBEEF,} }, /* onboard */ | ||
697 | { (unsigned long *)0x80802000, {0xDEADBEEF,} }, /* onboard */ | ||
698 | { (unsigned long *)0x80804000, {0xDEADBEEF,} }, /* onboard */ | ||
699 | { (unsigned long *)0x80810000, {0xDEADBEEF,} }, /* slot A/1 */ | ||
700 | { (unsigned long *)0x80820000, {0xDEADBEEF,} }, /* slot B/2 */ | ||
701 | { (unsigned long *)0x80840000, {0xDEADBEEF,} } /* slot C/3 */ | ||
702 | }; | ||
703 | |||
704 | |||
705 | |||
706 | /* | ||
707 | * The following code modifies the PCI Command register | ||
708 | * to enable memory and I/O accesses. | ||
709 | */ | ||
710 | void | ||
711 | unlockVideo(int slot) | ||
712 | { | ||
713 | volatile unsigned char * ppci; | ||
714 | |||
715 | ppci = (unsigned char * )PCI_slots[slot].config_addr; | ||
716 | ppci[4] = 0x0003; /* enable memory and I/O accesses */ | ||
717 | ppci[0x10] = 0x00000; /* turn off memory mapping */ | ||
718 | ppci[0x11] = 0x00000; /* mem_base = 0 */ | ||
719 | ppci[0x12] = 0x00000; | ||
720 | ppci[0x13] = 0x00000; | ||
721 | __asm__ volatile("eieio"); | ||
722 | |||
723 | outb(0x3d4, 0x11); | ||
724 | outb(0x3d5, 0x0e); /* unlock CR0-CR7 */ | ||
725 | } | ||
726 | |||
727 | long | ||
728 | SwapBytes(long lv) /* turn little endian into big indian long */ | ||
729 | { | ||
730 | long t; | ||
731 | t = (lv&0x000000FF) << 24; | ||
732 | t |= (lv&0x0000FF00) << 8; | ||
733 | t |= (lv&0x00FF0000) >> 8; | ||
734 | t |= (lv&0xFF000000) >> 24; | ||
735 | return(t); | ||
736 | } | ||
737 | |||
738 | |||
739 | #define DEVID 0 | ||
740 | #define CMD 1 | ||
741 | #define CLASS 2 | ||
742 | #define MEMBASE 4 | ||
743 | |||
744 | int | ||
745 | scanPCI(int start_slt) | ||
746 | { | ||
747 | int slt, r; | ||
748 | struct PCI_ConfigInfo *pslot; | ||
749 | int theSlot = -1; | ||
750 | int highVgaSlot = 0; | ||
751 | |||
752 | for ( slt = start_slt + 1; slt < NSLOTS; slt++) { | ||
753 | pslot = &PCI_slots[slt]; | ||
754 | for ( r = 0; r < NPCIREGS; r++) { | ||
755 | pslot->regs[r] = SwapBytes ( pslot->config_addr[r] ); | ||
756 | } | ||
757 | /* card in slot ? */ | ||
758 | if ( pslot->regs[DEVID] != 0xFFFFFFFF ) { | ||
759 | /* VGA ? */ | ||
760 | if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) || | ||
761 | ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x00010000)) { | ||
762 | highVgaSlot = slt; | ||
763 | /* did firmware enable it ? */ | ||
764 | if ( (pslot->regs[CMD] & 0x03) ) { | ||
765 | theSlot = slt; | ||
766 | break; | ||
767 | } | ||
768 | } | ||
769 | } | ||
770 | } | ||
771 | |||
772 | return ( theSlot ); | ||
773 | } | ||
774 | |||
775 | /* return Vendor ID of card in the slot */ | ||
776 | static | ||
777 | int PCIVendor(int slotnum) { | ||
778 | struct PCI_ConfigInfo *pslot; | ||
779 | |||
780 | pslot = &PCI_slots[slotnum]; | ||
781 | |||
782 | return (pslot->regs[DEVID] & 0xFFFF); | ||
783 | } | ||
784 | |||
785 | #ifdef DEBUG | ||
786 | static | ||
787 | void printslots(void) | ||
788 | { | ||
789 | int i; | ||
790 | #if 0 | ||
791 | struct PCI_ConfigInfo *pslot; | ||
792 | #endif | ||
793 | for(i=0; i < NSLOTS; i++) { | ||
794 | #if 0 | ||
795 | pslot = &PCI_slots[i]; | ||
796 | printf("Slot: %d, Addr: %x, Vendor: %08x, Class: %08x\n", | ||
797 | i, pslot->config_addr, pslot->regs[0], pslot->regs[2]); | ||
798 | #else | ||
799 | puts("PCI Slot number: "); puthex(i); | ||
800 | puts(" Vendor ID: "); | ||
801 | puthex(PCIVendor(i)); puts("\n"); | ||
802 | #endif | ||
803 | } | ||
804 | } | ||
805 | #endif /* DEBUG */ | ||