]> git.proxmox.com Git - qemu.git/blame - hw/pl110_template.h
PPC: Fix TLB invalidation bug within the PPC interrupt handler.
[qemu.git] / hw / pl110_template.h
CommitLineData
5fafdf24 1/*
bdd5003a
PB
2 * Arm PrimeCell PL110 Color LCD Controller
3 *
4 * Copyright (c) 2005 CodeSourcery, LLC.
5 * Written by Paul Brook
6 *
8e31bf38 7 * This code is licensed under the GNU LGPL
bdd5003a
PB
8 *
9 * Framebuffer format conversion routines.
10 */
11
12#ifndef ORDER
13
14#if BITS == 8
15#define COPY_PIXEL(to, from) *(to++) = from
16#elif BITS == 15 || BITS == 16
17#define COPY_PIXEL(to, from) *(uint16_t *)to = from; to += 2;
5fafdf24 18#elif BITS == 24
bdd5003a
PB
19#define COPY_PIXEL(to, from) \
20 *(to++) = from; *(to++) = (from) >> 8; *(to++) = (from) >> 16
21#elif BITS == 32
22#define COPY_PIXEL(to, from) *(uint32_t *)to = from; to += 4;
23#else
24#error unknown bit depth
25#endif
26
e9c05b42
AZ
27#undef RGB
28#define BORDER bgr
bdd5003a
PB
29#define ORDER 0
30#include "pl110_template.h"
31#define ORDER 1
32#include "pl110_template.h"
33#define ORDER 2
34#include "pl110_template.h"
e9c05b42
AZ
35#undef BORDER
36#define RGB
37#define BORDER rgb
38#define ORDER 0
39#include "pl110_template.h"
40#define ORDER 1
41#include "pl110_template.h"
42#define ORDER 2
43#include "pl110_template.h"
44#undef BORDER
bdd5003a 45
4fbf5556 46static drawfn glue(pl110_draw_fn_,BITS)[48] =
bdd5003a 47{
e9c05b42
AZ
48 glue(pl110_draw_line1_lblp_bgr,BITS),
49 glue(pl110_draw_line2_lblp_bgr,BITS),
50 glue(pl110_draw_line4_lblp_bgr,BITS),
51 glue(pl110_draw_line8_lblp_bgr,BITS),
4fbf5556 52 glue(pl110_draw_line16_555_lblp_bgr,BITS),
e9c05b42 53 glue(pl110_draw_line32_lblp_bgr,BITS),
4fbf5556
PM
54 glue(pl110_draw_line16_lblp_bgr,BITS),
55 glue(pl110_draw_line12_lblp_bgr,BITS),
e9c05b42
AZ
56
57 glue(pl110_draw_line1_bbbp_bgr,BITS),
58 glue(pl110_draw_line2_bbbp_bgr,BITS),
59 glue(pl110_draw_line4_bbbp_bgr,BITS),
60 glue(pl110_draw_line8_bbbp_bgr,BITS),
4fbf5556 61 glue(pl110_draw_line16_555_bbbp_bgr,BITS),
e9c05b42 62 glue(pl110_draw_line32_bbbp_bgr,BITS),
4fbf5556
PM
63 glue(pl110_draw_line16_bbbp_bgr,BITS),
64 glue(pl110_draw_line12_bbbp_bgr,BITS),
e9c05b42
AZ
65
66 glue(pl110_draw_line1_lbbp_bgr,BITS),
67 glue(pl110_draw_line2_lbbp_bgr,BITS),
68 glue(pl110_draw_line4_lbbp_bgr,BITS),
69 glue(pl110_draw_line8_lbbp_bgr,BITS),
4fbf5556 70 glue(pl110_draw_line16_555_lbbp_bgr,BITS),
e9c05b42 71 glue(pl110_draw_line32_lbbp_bgr,BITS),
4fbf5556
PM
72 glue(pl110_draw_line16_lbbp_bgr,BITS),
73 glue(pl110_draw_line12_lbbp_bgr,BITS),
e9c05b42
AZ
74
75 glue(pl110_draw_line1_lblp_rgb,BITS),
76 glue(pl110_draw_line2_lblp_rgb,BITS),
77 glue(pl110_draw_line4_lblp_rgb,BITS),
78 glue(pl110_draw_line8_lblp_rgb,BITS),
4fbf5556 79 glue(pl110_draw_line16_555_lblp_rgb,BITS),
e9c05b42 80 glue(pl110_draw_line32_lblp_rgb,BITS),
4fbf5556
PM
81 glue(pl110_draw_line16_lblp_rgb,BITS),
82 glue(pl110_draw_line12_lblp_rgb,BITS),
e9c05b42
AZ
83
84 glue(pl110_draw_line1_bbbp_rgb,BITS),
85 glue(pl110_draw_line2_bbbp_rgb,BITS),
86 glue(pl110_draw_line4_bbbp_rgb,BITS),
87 glue(pl110_draw_line8_bbbp_rgb,BITS),
4fbf5556 88 glue(pl110_draw_line16_555_bbbp_rgb,BITS),
e9c05b42 89 glue(pl110_draw_line32_bbbp_rgb,BITS),
4fbf5556
PM
90 glue(pl110_draw_line16_bbbp_rgb,BITS),
91 glue(pl110_draw_line12_bbbp_rgb,BITS),
e9c05b42
AZ
92
93 glue(pl110_draw_line1_lbbp_rgb,BITS),
94 glue(pl110_draw_line2_lbbp_rgb,BITS),
95 glue(pl110_draw_line4_lbbp_rgb,BITS),
96 glue(pl110_draw_line8_lbbp_rgb,BITS),
4fbf5556 97 glue(pl110_draw_line16_555_lbbp_rgb,BITS),
e9c05b42 98 glue(pl110_draw_line32_lbbp_rgb,BITS),
4fbf5556
PM
99 glue(pl110_draw_line16_lbbp_rgb,BITS),
100 glue(pl110_draw_line12_lbbp_rgb,BITS),
bdd5003a
PB
101};
102
103#undef BITS
104#undef COPY_PIXEL
105
106#else
107
108#if ORDER == 0
e9c05b42 109#define NAME glue(glue(lblp_, BORDER), BITS)
e2542fe2 110#ifdef HOST_WORDS_BIGENDIAN
bdd5003a
PB
111#define SWAP_WORDS 1
112#endif
113#elif ORDER == 1
e9c05b42 114#define NAME glue(glue(bbbp_, BORDER), BITS)
e2542fe2 115#ifndef HOST_WORDS_BIGENDIAN
bdd5003a
PB
116#define SWAP_WORDS 1
117#endif
118#else
119#define SWAP_PIXELS 1
e9c05b42 120#define NAME glue(glue(lbbp_, BORDER), BITS)
e2542fe2 121#ifdef HOST_WORDS_BIGENDIAN
bdd5003a
PB
122#define SWAP_WORDS 1
123#endif
124#endif
125
126#define FN_2(x, y) FN(x, y) FN(x+1, y)
1f9519c9 127#define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
bdd5003a
PB
128#define FN_8(y) FN_4(0, y) FN_4(4, y)
129
714fa308 130static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a 131{
714fa308 132 uint32_t *pallette = opaque;
bdd5003a
PB
133 uint32_t data;
134 while (width > 0) {
135 data = *(uint32_t *)src;
136#ifdef SWAP_PIXELS
137#define FN(x, y) COPY_PIXEL(d, pallette[(data >> (y + 7 - (x))) & 1]);
138#else
139#define FN(x, y) COPY_PIXEL(d, pallette[(data >> ((x) + y)) & 1]);
140#endif
be9d3657 141#ifdef SWAP_WORDS
bdd5003a
PB
142 FN_8(24)
143 FN_8(16)
144 FN_8(8)
145 FN_8(0)
146#else
147 FN_8(0)
148 FN_8(8)
149 FN_8(16)
150 FN_8(24)
151#endif
152#undef FN
153 width -= 32;
154 src += 4;
155 }
156}
157
714fa308 158static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a 159{
714fa308 160 uint32_t *pallette = opaque;
bdd5003a
PB
161 uint32_t data;
162 while (width > 0) {
163 data = *(uint32_t *)src;
164#ifdef SWAP_PIXELS
165#define FN(x, y) COPY_PIXEL(d, pallette[(data >> (y + 6 - (x)*2)) & 3]);
166#else
167#define FN(x, y) COPY_PIXEL(d, pallette[(data >> ((x)*2 + y)) & 3]);
168#endif
be9d3657 169#ifdef SWAP_WORDS
bdd5003a
PB
170 FN_4(0, 24)
171 FN_4(0, 16)
172 FN_4(0, 8)
173 FN_4(0, 0)
174#else
175 FN_4(0, 0)
176 FN_4(0, 8)
177 FN_4(0, 16)
178 FN_4(0, 24)
179#endif
180#undef FN
181 width -= 16;
182 src += 4;
183 }
184}
185
714fa308 186static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a 187{
714fa308 188 uint32_t *pallette = opaque;
bdd5003a
PB
189 uint32_t data;
190 while (width > 0) {
191 data = *(uint32_t *)src;
192#ifdef SWAP_PIXELS
193#define FN(x, y) COPY_PIXEL(d, pallette[(data >> (y + 4 - (x)*4)) & 0xf]);
194#else
195#define FN(x, y) COPY_PIXEL(d, pallette[(data >> ((x)*4 + y)) & 0xf]);
196#endif
be9d3657 197#ifdef SWAP_WORDS
bdd5003a
PB
198 FN_2(0, 24)
199 FN_2(0, 16)
200 FN_2(0, 8)
201 FN_2(0, 0)
202#else
203 FN_2(0, 0)
204 FN_2(0, 8)
205 FN_2(0, 16)
206 FN_2(0, 24)
207#endif
208#undef FN
209 width -= 8;
210 src += 4;
211 }
212}
213
714fa308 214static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a 215{
714fa308 216 uint32_t *pallette = opaque;
bdd5003a
PB
217 uint32_t data;
218 while (width > 0) {
219 data = *(uint32_t *)src;
220#define FN(x) COPY_PIXEL(d, pallette[(data >> (x)) & 0xff]);
be9d3657 221#ifdef SWAP_WORDS
bdd5003a
PB
222 FN(24)
223 FN(16)
224 FN(8)
225 FN(0)
226#else
227 FN(0)
228 FN(8)
229 FN(16)
230 FN(24)
231#endif
232#undef FN
233 width -= 4;
234 src += 4;
235 }
236}
237
714fa308 238static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a
PB
239{
240 uint32_t data;
241 unsigned int r, g, b;
242 while (width > 0) {
243 data = *(uint32_t *)src;
be9d3657 244#ifdef SWAP_WORDS
bdd5003a
PB
245 data = bswap32(data);
246#endif
e9c05b42
AZ
247#ifdef RGB
248#define LSB r
249#define MSB b
250#else
251#define LSB b
252#define MSB r
253#endif
bdd5003a 254#if 0
e9c05b42 255 LSB = data & 0x1f;
bdd5003a
PB
256 data >>= 5;
257 g = data & 0x3f;
258 data >>= 6;
e9c05b42 259 MSB = data & 0x1f;
bdd5003a
PB
260 data >>= 5;
261#else
e9c05b42 262 LSB = (data & 0x1f) << 3;
bdd5003a
PB
263 data >>= 5;
264 g = (data & 0x3f) << 2;
265 data >>= 6;
e9c05b42 266 MSB = (data & 0x1f) << 3;
bdd5003a
PB
267 data >>= 5;
268#endif
269 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
e9c05b42 270 LSB = (data & 0x1f) << 3;
bdd5003a
PB
271 data >>= 5;
272 g = (data & 0x3f) << 2;
273 data >>= 6;
e9c05b42 274 MSB = (data & 0x1f) << 3;
bdd5003a
PB
275 data >>= 5;
276 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
e9c05b42
AZ
277#undef MSB
278#undef LSB
bdd5003a
PB
279 width -= 2;
280 src += 4;
281 }
282}
283
714fa308 284static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
bdd5003a
PB
285{
286 uint32_t data;
287 unsigned int r, g, b;
288 while (width > 0) {
289 data = *(uint32_t *)src;
e9c05b42
AZ
290#ifdef RGB
291#define LSB r
292#define MSB b
293#else
294#define LSB b
295#define MSB r
296#endif
399a4e21 297#ifndef SWAP_WORDS
e9c05b42 298 LSB = data & 0xff;
bdd5003a 299 g = (data >> 8) & 0xff;
e9c05b42 300 MSB = (data >> 16) & 0xff;
bdd5003a 301#else
e9c05b42 302 LSB = (data >> 24) & 0xff;
bdd5003a 303 g = (data >> 16) & 0xff;
e9c05b42 304 MSB = (data >> 8) & 0xff;
bdd5003a
PB
305#endif
306 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
e9c05b42
AZ
307#undef MSB
308#undef LSB
bdd5003a
PB
309 width--;
310 src += 4;
311 }
312}
313
4fbf5556
PM
314static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
315{
316 /* RGB 555 plus an intensity bit (which we ignore) */
317 uint32_t data;
318 unsigned int r, g, b;
319 while (width > 0) {
320 data = *(uint32_t *)src;
321#ifdef SWAP_WORDS
322 data = bswap32(data);
323#endif
324#ifdef RGB
325#define LSB r
326#define MSB b
327#else
328#define LSB b
329#define MSB r
330#endif
331 LSB = (data & 0x1f) << 3;
332 data >>= 5;
333 g = (data & 0x1f) << 3;
334 data >>= 5;
335 MSB = (data & 0x1f) << 3;
336 data >>= 5;
337 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
338 LSB = (data & 0x1f) << 3;
339 data >>= 5;
340 g = (data & 0x1f) << 3;
341 data >>= 5;
342 MSB = (data & 0x1f) << 3;
343 data >>= 6;
344 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
345#undef MSB
346#undef LSB
347 width -= 2;
348 src += 4;
349 }
350}
351
352static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
353{
354 /* RGB 444 with 4 bits of zeroes at the top of each halfword */
355 uint32_t data;
356 unsigned int r, g, b;
357 while (width > 0) {
358 data = *(uint32_t *)src;
359#ifdef SWAP_WORDS
360 data = bswap32(data);
361#endif
362#ifdef RGB
363#define LSB r
364#define MSB b
365#else
366#define LSB b
367#define MSB r
368#endif
369 LSB = (data & 0xf) << 4;
370 data >>= 4;
371 g = (data & 0xf) << 4;
372 data >>= 4;
373 MSB = (data & 0xf) << 4;
374 data >>= 8;
375 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
376 LSB = (data & 0xf) << 4;
377 data >>= 4;
378 g = (data & 0xf) << 4;
379 data >>= 4;
380 MSB = (data & 0xf) << 4;
381 data >>= 8;
382 COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
383#undef MSB
384#undef LSB
385 width -= 2;
386 src += 4;
387 }
388}
389
bdd5003a
PB
390#undef SWAP_PIXELS
391#undef NAME
392#undef SWAP_WORDS
393#undef ORDER
394
395#endif