xref: /openbmc/linux/drivers/tty/vt/consolemap.c (revision 4f3db074)
1 /*
2  * consolemap.c
3  *
4  * Mapping from internal code (such as Latin-1 or Unicode or IBM PC code)
5  * to font positions.
6  *
7  * aeb, 950210
8  *
9  * Support for multiple unimaps by Jakub Jelinek <jj@ultra.linux.cz>, July 1998
10  *
11  * Fix bug in inverse translation. Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998
12  */
13 
14 #include <linux/module.h>
15 #include <linux/kd.h>
16 #include <linux/errno.h>
17 #include <linux/mm.h>
18 #include <linux/slab.h>
19 #include <linux/init.h>
20 #include <linux/tty.h>
21 #include <asm/uaccess.h>
22 #include <linux/console.h>
23 #include <linux/consolemap.h>
24 #include <linux/vt_kern.h>
25 
26 static unsigned short translations[][256] = {
27   /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
28   {
29     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
30     0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
31     0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
32     0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
33     0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
34     0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
35     0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
36     0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
37     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
38     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
39     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
40     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
41     0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
42     0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
43     0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
44     0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
45     0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
46     0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
47     0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
48     0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
49     0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
50     0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
51     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
52     0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
53     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
54     0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
55     0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
56     0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
57     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
58     0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
59     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
60     0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
61   },
62   /* VT100 graphics mapped to Unicode */
63   {
64     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
65     0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
66     0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
67     0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
68     0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
69     0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f,
70     0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
71     0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
72     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
73     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
74     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
75     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
76     0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
77     0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
78     0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
79     0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
80     0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
81     0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
82     0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
83     0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
84     0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
85     0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
86     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
87     0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
88     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
89     0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
90     0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
91     0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
92     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
93     0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
94     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
95     0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
96   },
97   /* IBM Codepage 437 mapped to Unicode */
98   {
99     0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
100     0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
101     0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
102     0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc,
103     0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
104     0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
105     0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
106     0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
107     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
108     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
109     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
110     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
111     0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
112     0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
113     0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
114     0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
115     0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
116     0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
117     0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
118     0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
119     0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
120     0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
121     0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
122     0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
123     0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
124     0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
125     0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
126     0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
127     0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
128     0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
129     0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
130     0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
131   },
132   /* User mapping -- default to codes for direct font mapping */
133   {
134     0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
135     0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
136     0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
137     0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
138     0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
139     0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f,
140     0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
141     0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f,
142     0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047,
143     0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f,
144     0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057,
145     0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f,
146     0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067,
147     0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f,
148     0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077,
149     0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f,
150     0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087,
151     0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f,
152     0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097,
153     0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f,
154     0xf0a0, 0xf0a1, 0xf0a2, 0xf0a3, 0xf0a4, 0xf0a5, 0xf0a6, 0xf0a7,
155     0xf0a8, 0xf0a9, 0xf0aa, 0xf0ab, 0xf0ac, 0xf0ad, 0xf0ae, 0xf0af,
156     0xf0b0, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xf0b6, 0xf0b7,
157     0xf0b8, 0xf0b9, 0xf0ba, 0xf0bb, 0xf0bc, 0xf0bd, 0xf0be, 0xf0bf,
158     0xf0c0, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xf0c5, 0xf0c6, 0xf0c7,
159     0xf0c8, 0xf0c9, 0xf0ca, 0xf0cb, 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf,
160     0xf0d0, 0xf0d1, 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d7,
161     0xf0d8, 0xf0d9, 0xf0da, 0xf0db, 0xf0dc, 0xf0dd, 0xf0de, 0xf0df,
162     0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7,
163     0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
164     0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
165     0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
166   }
167 };
168 
169 /* The standard kernel character-to-font mappings are not invertible
170    -- this is just a best effort. */
171 
172 #define MAX_GLYPH 512		/* Max possible glyph value */
173 
174 static int inv_translate[MAX_NR_CONSOLES];
175 
176 struct uni_pagedir {
177 	u16 		**uni_pgdir[32];
178 	unsigned long	refcount;
179 	unsigned long	sum;
180 	unsigned char	*inverse_translations[4];
181 	u16		*inverse_trans_unicode;
182 };
183 
184 static struct uni_pagedir *dflt;
185 
186 static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, int i)
187 {
188 	int j, glyph;
189 	unsigned short *t = translations[i];
190 	unsigned char *q;
191 
192 	if (!p) return;
193 	q = p->inverse_translations[i];
194 
195 	if (!q) {
196 		q = p->inverse_translations[i] = kmalloc(MAX_GLYPH, GFP_KERNEL);
197 		if (!q) return;
198 	}
199 	memset(q, 0, MAX_GLYPH);
200 
201 	for (j = 0; j < E_TABSZ; j++) {
202 		glyph = conv_uni_to_pc(conp, t[j]);
203 		if (glyph >= 0 && glyph < MAX_GLYPH && q[glyph] < 32) {
204 			/* prefer '-' above SHY etc. */
205 		  	q[glyph] = j;
206 		}
207 	}
208 }
209 
210 static void set_inverse_trans_unicode(struct vc_data *conp,
211 				      struct uni_pagedir *p)
212 {
213 	int i, j, k, glyph;
214 	u16 **p1, *p2;
215 	u16 *q;
216 
217 	if (!p) return;
218 	q = p->inverse_trans_unicode;
219 	if (!q) {
220 		q = p->inverse_trans_unicode =
221 			kmalloc(MAX_GLYPH * sizeof(u16), GFP_KERNEL);
222 		if (!q)
223 			return;
224 	}
225 	memset(q, 0, MAX_GLYPH * sizeof(u16));
226 
227 	for (i = 0; i < 32; i++) {
228 		p1 = p->uni_pgdir[i];
229 		if (!p1)
230 			continue;
231 		for (j = 0; j < 32; j++) {
232 			p2 = p1[j];
233 			if (!p2)
234 				continue;
235 			for (k = 0; k < 64; k++) {
236 				glyph = p2[k];
237 				if (glyph >= 0 && glyph < MAX_GLYPH
238 					       && q[glyph] < 32)
239 		  			q[glyph] = (i << 11) + (j << 6) + k;
240 			}
241 		}
242 	}
243 }
244 
245 unsigned short *set_translate(int m, struct vc_data *vc)
246 {
247 	inv_translate[vc->vc_num] = m;
248 	return translations[m];
249 }
250 
251 /*
252  * Inverse translation is impossible for several reasons:
253  * 1. The font<->character maps are not 1-1.
254  * 2. The text may have been written while a different translation map
255  *    was active.
256  * Still, it is now possible to a certain extent to cut and paste non-ASCII.
257  */
258 u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode)
259 {
260 	struct uni_pagedir *p;
261 	int m;
262 	if (glyph < 0 || glyph >= MAX_GLYPH)
263 		return 0;
264 	else if (!(p = *conp->vc_uni_pagedir_loc))
265 		return glyph;
266 	else if (use_unicode) {
267 		if (!p->inverse_trans_unicode)
268 			return glyph;
269 		else
270 			return p->inverse_trans_unicode[glyph];
271 	} else {
272 		m = inv_translate[conp->vc_num];
273 		if (!p->inverse_translations[m])
274 			return glyph;
275 		else
276 			return p->inverse_translations[m][glyph];
277 	}
278 }
279 EXPORT_SYMBOL_GPL(inverse_translate);
280 
281 static void update_user_maps(void)
282 {
283 	int i;
284 	struct uni_pagedir *p, *q = NULL;
285 
286 	for (i = 0; i < MAX_NR_CONSOLES; i++) {
287 		if (!vc_cons_allocated(i))
288 			continue;
289 		p = *vc_cons[i].d->vc_uni_pagedir_loc;
290 		if (p && p != q) {
291 			set_inverse_transl(vc_cons[i].d, p, USER_MAP);
292 			set_inverse_trans_unicode(vc_cons[i].d, p);
293 			q = p;
294 		}
295 	}
296 }
297 
298 /*
299  * Load customizable translation table
300  * arg points to a 256 byte translation table.
301  *
302  * The "old" variants are for translation directly to font (using the
303  * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
304  * Unicodes explicitly.
305  */
306 int con_set_trans_old(unsigned char __user * arg)
307 {
308 	int i;
309 	unsigned short *p = translations[USER_MAP];
310 
311 	if (!access_ok(VERIFY_READ, arg, E_TABSZ))
312 		return -EFAULT;
313 
314 	console_lock();
315 	for (i=0; i<E_TABSZ ; i++) {
316 		unsigned char uc;
317 		__get_user(uc, arg+i);
318 		p[i] = UNI_DIRECT_BASE | uc;
319 	}
320 
321 	update_user_maps();
322 	console_unlock();
323 	return 0;
324 }
325 
326 int con_get_trans_old(unsigned char __user * arg)
327 {
328 	int i, ch;
329 	unsigned short *p = translations[USER_MAP];
330 
331 	if (!access_ok(VERIFY_WRITE, arg, E_TABSZ))
332 		return -EFAULT;
333 
334 	console_lock();
335 	for (i=0; i<E_TABSZ ; i++)
336 	{
337 		ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
338 		__put_user((ch & ~0xff) ? 0 : ch, arg+i);
339 	}
340 	console_unlock();
341 	return 0;
342 }
343 
344 int con_set_trans_new(ushort __user * arg)
345 {
346 	int i;
347 	unsigned short *p = translations[USER_MAP];
348 
349 	if (!access_ok(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short)))
350 		return -EFAULT;
351 
352 	console_lock();
353 	for (i=0; i<E_TABSZ ; i++) {
354 		unsigned short us;
355 		__get_user(us, arg+i);
356 		p[i] = us;
357 	}
358 
359 	update_user_maps();
360 	console_unlock();
361 	return 0;
362 }
363 
364 int con_get_trans_new(ushort __user * arg)
365 {
366 	int i;
367 	unsigned short *p = translations[USER_MAP];
368 
369 	if (!access_ok(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short)))
370 		return -EFAULT;
371 
372 	console_lock();
373 	for (i=0; i<E_TABSZ ; i++)
374 	  __put_user(p[i], arg+i);
375 	console_unlock();
376 
377 	return 0;
378 }
379 
380 /*
381  * Unicode -> current font conversion
382  *
383  * A font has at most 512 chars, usually 256.
384  * But one font position may represent several Unicode chars.
385  * A hashtable is somewhat of a pain to deal with, so use a
386  * "paged table" instead.  Simulation has shown the memory cost of
387  * this 3-level paged table scheme to be comparable to a hash table.
388  */
389 
390 extern u8 dfont_unicount[];	/* Defined in console_defmap.c */
391 extern u16 dfont_unitable[];
392 
393 static void con_release_unimap(struct uni_pagedir *p)
394 {
395 	u16 **p1;
396 	int i, j;
397 
398 	if (p == dflt) dflt = NULL;
399 	for (i = 0; i < 32; i++) {
400 		if ((p1 = p->uni_pgdir[i]) != NULL) {
401 			for (j = 0; j < 32; j++)
402 				kfree(p1[j]);
403 			kfree(p1);
404 		}
405 		p->uni_pgdir[i] = NULL;
406 	}
407 	for (i = 0; i < 4; i++) {
408 		kfree(p->inverse_translations[i]);
409 		p->inverse_translations[i] = NULL;
410 	}
411 	kfree(p->inverse_trans_unicode);
412 	p->inverse_trans_unicode = NULL;
413 }
414 
415 /* Caller must hold the console lock */
416 void con_free_unimap(struct vc_data *vc)
417 {
418 	struct uni_pagedir *p;
419 
420 	p = *vc->vc_uni_pagedir_loc;
421 	if (!p)
422 		return;
423 	*vc->vc_uni_pagedir_loc = NULL;
424 	if (--p->refcount)
425 		return;
426 	con_release_unimap(p);
427 	kfree(p);
428 }
429 
430 static int con_unify_unimap(struct vc_data *conp, struct uni_pagedir *p)
431 {
432 	int i, j, k;
433 	struct uni_pagedir *q;
434 
435 	for (i = 0; i < MAX_NR_CONSOLES; i++) {
436 		if (!vc_cons_allocated(i))
437 			continue;
438 		q = *vc_cons[i].d->vc_uni_pagedir_loc;
439 		if (!q || q == p || q->sum != p->sum)
440 			continue;
441 		for (j = 0; j < 32; j++) {
442 			u16 **p1, **q1;
443 			p1 = p->uni_pgdir[j]; q1 = q->uni_pgdir[j];
444 			if (!p1 && !q1)
445 				continue;
446 			if (!p1 || !q1)
447 				break;
448 			for (k = 0; k < 32; k++) {
449 				if (!p1[k] && !q1[k])
450 					continue;
451 				if (!p1[k] || !q1[k])
452 					break;
453 				if (memcmp(p1[k], q1[k], 64*sizeof(u16)))
454 					break;
455 			}
456 			if (k < 32)
457 				break;
458 		}
459 		if (j == 32) {
460 			q->refcount++;
461 			*conp->vc_uni_pagedir_loc = q;
462 			con_release_unimap(p);
463 			kfree(p);
464 			return 1;
465 		}
466 	}
467 	return 0;
468 }
469 
470 static int
471 con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
472 {
473 	int i, n;
474 	u16 **p1, *p2;
475 
476 	if (!(p1 = p->uni_pgdir[n = unicode >> 11])) {
477 		p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL);
478 		if (!p1) return -ENOMEM;
479 		for (i = 0; i < 32; i++)
480 			p1[i] = NULL;
481 	}
482 
483 	if (!(p2 = p1[n = (unicode >> 6) & 0x1f])) {
484 		p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL);
485 		if (!p2) return -ENOMEM;
486 		memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */
487 	}
488 
489 	p2[unicode & 0x3f] = fontpos;
490 
491 	p->sum += (fontpos << 20) + unicode;
492 
493 	return 0;
494 }
495 
496 /* ui is a leftover from using a hashtable, but might be used again
497    Caller must hold the lock */
498 static int con_do_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
499 {
500 	struct uni_pagedir *p, *q;
501 
502 	p = *vc->vc_uni_pagedir_loc;
503 	if (!p || --p->refcount) {
504 		q = kzalloc(sizeof(*p), GFP_KERNEL);
505 		if (!q) {
506 			if (p)
507 				p->refcount++;
508 			return -ENOMEM;
509 		}
510 		q->refcount=1;
511 		*vc->vc_uni_pagedir_loc = q;
512 	} else {
513 		if (p == dflt) dflt = NULL;
514 		p->refcount++;
515 		p->sum = 0;
516 		con_release_unimap(p);
517 	}
518 	return 0;
519 }
520 
521 int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
522 {
523 	int ret;
524 	console_lock();
525 	ret = con_do_clear_unimap(vc, ui);
526 	console_unlock();
527 	return ret;
528 }
529 
530 int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
531 {
532 	int err = 0, err1, i;
533 	struct uni_pagedir *p, *q;
534 
535 	if (!ct)
536 		return 0;
537 
538 	console_lock();
539 
540 	/* Save original vc_unipagdir_loc in case we allocate a new one */
541 	p = *vc->vc_uni_pagedir_loc;
542 
543 	if (!p) {
544 		err = -EINVAL;
545 
546 		goto out_unlock;
547 	}
548 
549 	if (p->refcount > 1) {
550 		int j, k;
551 		u16 **p1, *p2, l;
552 
553 		err1 = con_do_clear_unimap(vc, NULL);
554 		if (err1) {
555 			console_unlock();
556 			return err1;
557 		}
558 
559 		/*
560 		 * Since refcount was > 1, con_clear_unimap() allocated a
561 		 * a new uni_pagedir for this vc.  Re: p != q
562 		 */
563 		q = *vc->vc_uni_pagedir_loc;
564 
565 		/*
566 		 * uni_pgdir is a 32*32*64 table with rows allocated
567 		 * when its first entry is added.  The unicode value must
568 		 * still be incremented for empty rows.  We are copying
569 		 * entries from "p" (old) to "q" (new).
570 		 */
571 		l = 0;		/* unicode value */
572 		for (i = 0; i < 32; i++)
573 		if ((p1 = p->uni_pgdir[i]))
574 			for (j = 0; j < 32; j++)
575 			if ((p2 = p1[j])) {
576 				for (k = 0; k < 64; k++, l++)
577 				if (p2[k] != 0xffff) {
578 					/*
579 					 * Found one, copy entry for unicode
580 					 * l with fontpos value p2[k].
581 					 */
582 					err1 = con_insert_unipair(q, l, p2[k]);
583 					if (err1) {
584 						p->refcount++;
585 						*vc->vc_uni_pagedir_loc = p;
586 						con_release_unimap(q);
587 						kfree(q);
588 						console_unlock();
589 						return err1;
590 					}
591 				}
592 			} else {
593 				/* Account for row of 64 empty entries */
594 				l += 64;
595 			}
596 		else
597 			/* Account for empty table */
598 			l += 32 * 64;
599 
600 		/*
601 		 * Finished copying font table, set vc_uni_pagedir to new table
602 		 */
603 		p = q;
604 	} else if (p == dflt) {
605 		dflt = NULL;
606 	}
607 
608 	/*
609 	 * Insert user specified unicode pairs into new table.
610 	 */
611 	while (ct--) {
612 		unsigned short unicode, fontpos;
613 		__get_user(unicode, &list->unicode);
614 		__get_user(fontpos, &list->fontpos);
615 		if ((err1 = con_insert_unipair(p, unicode,fontpos)) != 0)
616 			err = err1;
617 		list++;
618 	}
619 
620 	/*
621 	 * Merge with fontmaps of any other virtual consoles.
622 	 */
623 	if (con_unify_unimap(vc, p)) {
624 		console_unlock();
625 		return err;
626 	}
627 
628 	for (i = 0; i <= 3; i++)
629 		set_inverse_transl(vc, p, i); /* Update inverse translations */
630 	set_inverse_trans_unicode(vc, p);
631 
632 out_unlock:
633 	console_unlock();
634 	return err;
635 }
636 
637 /**
638  *	con_set_default_unimap	-	set default unicode map
639  *	@vc: the console we are updating
640  *
641  *	Loads the unimap for the hardware font, as defined in uni_hash.tbl.
642  *	The representation used was the most compact I could come up
643  *	with.  This routine is executed at video setup, and when the
644  *	PIO_FONTRESET ioctl is called.
645  *
646  *	The caller must hold the console lock
647  */
648 int con_set_default_unimap(struct vc_data *vc)
649 {
650 	int i, j, err = 0, err1;
651 	u16 *q;
652 	struct uni_pagedir *p;
653 
654 	if (dflt) {
655 		p = *vc->vc_uni_pagedir_loc;
656 		if (p == dflt)
657 			return 0;
658 
659 		dflt->refcount++;
660 		*vc->vc_uni_pagedir_loc = dflt;
661 		if (p && !--p->refcount) {
662 			con_release_unimap(p);
663 			kfree(p);
664 		}
665 		return 0;
666 	}
667 
668 	/* The default font is always 256 characters */
669 
670 	err = con_do_clear_unimap(vc, NULL);
671 	if (err)
672 		return err;
673 
674 	p = *vc->vc_uni_pagedir_loc;
675 	q = dfont_unitable;
676 
677 	for (i = 0; i < 256; i++)
678 		for (j = dfont_unicount[i]; j; j--) {
679 			err1 = con_insert_unipair(p, *(q++), i);
680 			if (err1)
681 				err = err1;
682 		}
683 
684 	if (con_unify_unimap(vc, p)) {
685 		dflt = *vc->vc_uni_pagedir_loc;
686 		return err;
687 	}
688 
689 	for (i = 0; i <= 3; i++)
690 		set_inverse_transl(vc, p, i);	/* Update all inverse translations */
691 	set_inverse_trans_unicode(vc, p);
692 	dflt = p;
693 	return err;
694 }
695 EXPORT_SYMBOL(con_set_default_unimap);
696 
697 /**
698  *	con_copy_unimap		-	copy unimap between two vts
699  *	@dst_vc: target
700  *	@src_vt: source
701  *
702  *	The caller must hold the console lock when invoking this method
703  */
704 int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
705 {
706 	struct uni_pagedir *q;
707 
708 	if (!*src_vc->vc_uni_pagedir_loc)
709 		return -EINVAL;
710 	if (*dst_vc->vc_uni_pagedir_loc == *src_vc->vc_uni_pagedir_loc)
711 		return 0;
712 	con_free_unimap(dst_vc);
713 	q = *src_vc->vc_uni_pagedir_loc;
714 	q->refcount++;
715 	*dst_vc->vc_uni_pagedir_loc = q;
716 	return 0;
717 }
718 EXPORT_SYMBOL(con_copy_unimap);
719 
720 /**
721  *	con_get_unimap		-	get the unicode map
722  *	@vc: the console to read from
723  *
724  *	Read the console unicode data for this console. Called from the ioctl
725  *	handlers.
726  */
727 int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list)
728 {
729 	int i, j, k, ect;
730 	u16 **p1, *p2;
731 	struct uni_pagedir *p;
732 
733 	console_lock();
734 
735 	ect = 0;
736 	if (*vc->vc_uni_pagedir_loc) {
737 		p = *vc->vc_uni_pagedir_loc;
738 		for (i = 0; i < 32; i++)
739 		if ((p1 = p->uni_pgdir[i]))
740 			for (j = 0; j < 32; j++)
741 			if ((p2 = *(p1++)))
742 				for (k = 0; k < 64; k++) {
743 					if (*p2 < MAX_GLYPH && ect++ < ct) {
744 						__put_user((u_short)((i<<11)+(j<<6)+k),
745 							   &list->unicode);
746 						__put_user((u_short) *p2,
747 							   &list->fontpos);
748 						list++;
749 					}
750 					p2++;
751 				}
752 	}
753 	__put_user(ect, uct);
754 	console_unlock();
755 	return ((ect <= ct) ? 0 : -ENOMEM);
756 }
757 
758 /*
759  * Always use USER_MAP. These functions are used by the keyboard,
760  * which shouldn't be affected by G0/G1 switching, etc.
761  * If the user map still contains default values, i.e. the
762  * direct-to-font mapping, then assume user is using Latin1.
763  *
764  * FIXME: at some point we need to decide if we want to lock the table
765  * update element itself via the keyboard_event_lock for consistency with the
766  * keyboard driver as well as the consoles
767  */
768 /* may be called during an interrupt */
769 u32 conv_8bit_to_uni(unsigned char c)
770 {
771 	unsigned short uni = translations[USER_MAP][c];
772 	return uni == (0xf000 | c) ? c : uni;
773 }
774 
775 int conv_uni_to_8bit(u32 uni)
776 {
777 	int c;
778 	for (c = 0; c < 0x100; c++)
779 		if (translations[USER_MAP][c] == uni ||
780 		   (translations[USER_MAP][c] == (c | 0xf000) && uni == c))
781 			return c;
782 	return -1;
783 }
784 
785 int
786 conv_uni_to_pc(struct vc_data *conp, long ucs)
787 {
788 	int h;
789 	u16 **p1, *p2;
790 	struct uni_pagedir *p;
791 
792 	/* Only 16-bit codes supported at this time */
793 	if (ucs > 0xffff)
794 		return -4;		/* Not found */
795 	else if (ucs < 0x20)
796 		return -1;		/* Not a printable character */
797 	else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
798 		return -2;			/* Zero-width space */
799 	/*
800 	 * UNI_DIRECT_BASE indicates the start of the region in the User Zone
801 	 * which always has a 1:1 mapping to the currently loaded font.  The
802 	 * UNI_DIRECT_MASK indicates the bit span of the region.
803 	 */
804 	else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE)
805 		return ucs & UNI_DIRECT_MASK;
806 
807 	if (!*conp->vc_uni_pagedir_loc)
808 		return -3;
809 
810 	p = *conp->vc_uni_pagedir_loc;
811 	if ((p1 = p->uni_pgdir[ucs >> 11]) &&
812 	    (p2 = p1[(ucs >> 6) & 0x1f]) &&
813 	    (h = p2[ucs & 0x3f]) < MAX_GLYPH)
814 		return h;
815 
816 	return -4;		/* not found */
817 }
818 
819 /*
820  * This is called at sys_setup time, after memory and the console are
821  * initialized.  It must be possible to call kmalloc(..., GFP_KERNEL)
822  * from this function, hence the call from sys_setup.
823  */
824 void __init
825 console_map_init(void)
826 {
827 	int i;
828 
829 	for (i = 0; i < MAX_NR_CONSOLES; i++)
830 		if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
831 			con_set_default_unimap(vc_cons[i].d);
832 }
833 
834