source: mainline/uspace/drv/fb/kfb/port.c@ 7d276395

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7d276395 was bf9cb2f, checked in by Martin Decky <martin@…>, 11 years ago

complete the desired API semantics of physmem_map() and dmamem_map_anonymous() to be compatible with as_area_create()
(the user is allowed to request a specific virtual memory base address, the kernel uses an available base address if AS_AREA_ANY is used)

  • Property mode set to 100644
File size: 9.4 KB
Line 
1/*
2 * Copyright (c) 2006 Jakub Vana
3 * Copyright (c) 2006 Ondrej Palkovsky
4 * Copyright (c) 2008 Martin Decky
5 * Copyright (c) 2011 Petr Koupy
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * - Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * - The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/** @addtogroup kfb
33 * @{
34 */
35/**
36 * @file
37 */
38
39#include <abi/fb/visuals.h>
40#include <sys/types.h>
41#include <errno.h>
42
43#include <malloc.h>
44#include <mem.h>
45#include <as.h>
46#include <align.h>
47
48#include <sysinfo.h>
49#include <ddi.h>
50
51#include <adt/list.h>
52
53#include <io/mode.h>
54#include <io/pixelmap.h>
55#include <io/chargrid.h>
56
57#include <pixconv.h>
58
59#include <graph.h>
60
61#include "kfb.h"
62#include "port.h"
63
64#define FB_POS(x, y) ((y) * kfb.scanline + (x) * kfb.pixel_bytes)
65
66typedef struct {
67 sysarg_t width;
68 sysarg_t height;
69 size_t offset;
70 size_t scanline;
71 visual_t visual;
72
73 pixel2visual_t pixel2visual;
74 visual2pixel_t visual2pixel;
75 visual_mask_t visual_mask;
76 size_t pixel_bytes;
77
78 size_t size;
79 uint8_t *addr;
80} kfb_t;
81
82static kfb_t kfb;
83
84static vslmode_list_element_t pixel_mode;
85
86static pixel_t color_table[16] = {
87 [COLOR_BLACK] = 0x000000,
88 [COLOR_BLUE] = 0x0000f0,
89 [COLOR_GREEN] = 0x00f000,
90 [COLOR_CYAN] = 0x00f0f0,
91 [COLOR_RED] = 0xf00000,
92 [COLOR_MAGENTA] = 0xf000f0,
93 [COLOR_YELLOW] = 0xf0f000,
94 [COLOR_WHITE] = 0xf0f0f0,
95
96 [COLOR_BLACK + 8] = 0x000000,
97 [COLOR_BLUE + 8] = 0x0000ff,
98 [COLOR_GREEN + 8] = 0x00ff00,
99 [COLOR_CYAN + 8] = 0x00ffff,
100 [COLOR_RED + 8] = 0xff0000,
101 [COLOR_MAGENTA + 8] = 0xff00ff,
102 [COLOR_YELLOW + 8] = 0xffff00,
103 [COLOR_WHITE + 8] = 0xffffff,
104};
105
106static inline void attrs_rgb(char_attrs_t attrs, pixel_t *bgcolor, pixel_t *fgcolor)
107{
108 switch (attrs.type) {
109 case CHAR_ATTR_STYLE:
110 switch (attrs.val.style) {
111 case STYLE_NORMAL:
112 *bgcolor = color_table[COLOR_WHITE];
113 *fgcolor = color_table[COLOR_BLACK];
114 break;
115 case STYLE_EMPHASIS:
116 *bgcolor = color_table[COLOR_WHITE];
117 *fgcolor = color_table[COLOR_RED];
118 break;
119 case STYLE_INVERTED:
120 *bgcolor = color_table[COLOR_BLACK];
121 *fgcolor = color_table[COLOR_WHITE];
122 break;
123 case STYLE_SELECTED:
124 *bgcolor = color_table[COLOR_RED];
125 *fgcolor = color_table[COLOR_WHITE];
126 break;
127 }
128 break;
129 case CHAR_ATTR_INDEX:
130 *bgcolor = color_table[(attrs.val.index.bgcolor & 7) |
131 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)];
132 *fgcolor = color_table[(attrs.val.index.fgcolor & 7) |
133 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)];
134 break;
135 case CHAR_ATTR_RGB:
136 *bgcolor = attrs.val.rgb.bgcolor;
137 *fgcolor = attrs.val.rgb.fgcolor;
138 break;
139 }
140}
141
142static int kfb_claim(visualizer_t *vs)
143{
144 return EOK;
145}
146
147static int kfb_yield(visualizer_t *vs)
148{
149 if (vs->mode_set) {
150 vs->ops.handle_damage = NULL;
151 }
152
153 return EOK;
154}
155
156static int kfb_handle_damage_pixels(visualizer_t *vs,
157 sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
158 sysarg_t x_offset, sysarg_t y_offset)
159{
160 pixelmap_t *map = &vs->cells;
161
162 if (x_offset == 0 && y_offset == 0) {
163 /* Faster damage routine ignoring offsets. */
164 for (sysarg_t y = y0; y < height + y0; ++y) {
165 pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
166 for (sysarg_t x = x0; x < width + x0; ++x) {
167 kfb.pixel2visual(kfb.addr + FB_POS(x, y), *pixel++);
168 }
169 }
170 } else {
171 for (sysarg_t y = y0; y < height + y0; ++y) {
172 for (sysarg_t x = x0; x < width + x0; ++x) {
173 kfb.pixel2visual(kfb.addr + FB_POS(x, y),
174 *pixelmap_pixel_at(map,
175 (x + x_offset) % map->width,
176 (y + y_offset) % map->height));
177 }
178 }
179 }
180
181 return EOK;
182}
183
184static int kfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
185{
186 vs->ops.handle_damage = kfb_handle_damage_pixels;
187 return EOK;
188}
189
190static int kfb_suspend(visualizer_t *vs)
191{
192 return EOK;
193}
194
195static int kfb_wakeup(visualizer_t *vs)
196{
197 return EOK;
198}
199
200static visualizer_ops_t kfb_ops = {
201 .claim = kfb_claim,
202 .yield = kfb_yield,
203 .change_mode = kfb_change_mode,
204 .handle_damage = NULL,
205 .suspend = kfb_suspend,
206 .wakeup = kfb_wakeup
207};
208
209int port_init(ddf_dev_t *dev)
210{
211 sysarg_t present;
212 int rc = sysinfo_get_value("fb", &present);
213 if (rc != EOK)
214 present = false;
215
216 if (!present)
217 return ENOENT;
218
219 sysarg_t kind;
220 rc = sysinfo_get_value("fb.kind", &kind);
221 if (rc != EOK)
222 kind = (sysarg_t) -1;
223
224 if (kind != 1)
225 return EINVAL;
226
227 sysarg_t paddr;
228 rc = sysinfo_get_value("fb.address.physical", &paddr);
229 if (rc != EOK)
230 return rc;
231
232 sysarg_t offset;
233 rc = sysinfo_get_value("fb.offset", &offset);
234 if (rc != EOK)
235 offset = 0;
236
237 sysarg_t width;
238 rc = sysinfo_get_value("fb.width", &width);
239 if (rc != EOK)
240 return rc;
241
242 sysarg_t height;
243 rc = sysinfo_get_value("fb.height", &height);
244 if (rc != EOK)
245 return rc;
246
247 sysarg_t scanline;
248 rc = sysinfo_get_value("fb.scanline", &scanline);
249 if (rc != EOK)
250 return rc;
251
252 sysarg_t visual;
253 rc = sysinfo_get_value("fb.visual", &visual);
254 if (rc != EOK)
255 return rc;
256
257 kfb.width = width;
258 kfb.height = height;
259 kfb.offset = offset;
260 kfb.scanline = scanline;
261 kfb.visual = visual;
262
263 switch (visual) {
264 case VISUAL_INDIRECT_8:
265 kfb.pixel2visual = pixel2bgr_323;
266 kfb.visual2pixel = bgr_323_2pixel;
267 kfb.visual_mask = visual_mask_323;
268 kfb.pixel_bytes = 1;
269 break;
270 case VISUAL_RGB_5_5_5_LE:
271 kfb.pixel2visual = pixel2rgb_555_le;
272 kfb.visual2pixel = rgb_555_le_2pixel;
273 kfb.visual_mask = visual_mask_555;
274 kfb.pixel_bytes = 2;
275 break;
276 case VISUAL_RGB_5_5_5_BE:
277 kfb.pixel2visual = pixel2rgb_555_be;
278 kfb.visual2pixel = rgb_555_be_2pixel;
279 kfb.visual_mask = visual_mask_555;
280 kfb.pixel_bytes = 2;
281 break;
282 case VISUAL_RGB_5_6_5_LE:
283 kfb.pixel2visual = pixel2rgb_565_le;
284 kfb.visual2pixel = rgb_565_le_2pixel;
285 kfb.visual_mask = visual_mask_565;
286 kfb.pixel_bytes = 2;
287 break;
288 case VISUAL_RGB_5_6_5_BE:
289 kfb.pixel2visual = pixel2rgb_565_be;
290 kfb.visual2pixel = rgb_565_be_2pixel;
291 kfb.visual_mask = visual_mask_565;
292 kfb.pixel_bytes = 2;
293 break;
294 case VISUAL_RGB_8_8_8:
295 kfb.pixel2visual = pixel2rgb_888;
296 kfb.visual2pixel = rgb_888_2pixel;
297 kfb.visual_mask = visual_mask_888;
298 kfb.pixel_bytes = 3;
299 break;
300 case VISUAL_BGR_8_8_8:
301 kfb.pixel2visual = pixel2bgr_888;
302 kfb.visual2pixel = bgr_888_2pixel;
303 kfb.visual_mask = visual_mask_888;
304 kfb.pixel_bytes = 3;
305 break;
306 case VISUAL_RGB_8_8_8_0:
307 kfb.pixel2visual = pixel2rgb_8880;
308 kfb.visual2pixel = rgb_8880_2pixel;
309 kfb.visual_mask = visual_mask_8880;
310 kfb.pixel_bytes = 4;
311 break;
312 case VISUAL_RGB_0_8_8_8:
313 kfb.pixel2visual = pixel2rgb_0888;
314 kfb.visual2pixel = rgb_0888_2pixel;
315 kfb.visual_mask = visual_mask_0888;
316 kfb.pixel_bytes = 4;
317 break;
318 case VISUAL_BGR_0_8_8_8:
319 kfb.pixel2visual = pixel2bgr_0888;
320 kfb.visual2pixel = bgr_0888_2pixel;
321 kfb.visual_mask = visual_mask_0888;
322 kfb.pixel_bytes = 4;
323 break;
324 case VISUAL_BGR_8_8_8_0:
325 kfb.pixel2visual = pixel2bgr_8880;
326 kfb.visual2pixel = bgr_8880_2pixel;
327 kfb.visual_mask = visual_mask_8880;
328 kfb.pixel_bytes = 4;
329 break;
330 default:
331 return EINVAL;
332 }
333
334 kfb.size = scanline * height;
335 kfb.addr = AS_AREA_ANY;
336
337 rc = physmem_map(paddr + offset,
338 ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
339 AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
340 if (rc != EOK)
341 return rc;
342
343 ddf_fun_t *fun_vs = ddf_fun_create(dev, fun_exposed, "vsl0");
344 if (fun_vs == NULL) {
345 as_area_destroy(kfb.addr);
346 return ENOMEM;
347 }
348 ddf_fun_set_ops(fun_vs, &graph_vsl_device_ops);
349
350 visualizer_t *vs = ddf_fun_data_alloc(fun_vs, sizeof(visualizer_t));
351 if (vs == NULL) {
352 as_area_destroy(kfb.addr);
353 return ENOMEM;
354 }
355 graph_init_visualizer(vs);
356
357 pixel_mode.mode.index = 0;
358 pixel_mode.mode.version = 0;
359 pixel_mode.mode.refresh_rate = 0;
360 pixel_mode.mode.screen_aspect.width = width;
361 pixel_mode.mode.screen_aspect.height = height;
362 pixel_mode.mode.screen_width = width;
363 pixel_mode.mode.screen_height = height;
364 pixel_mode.mode.cell_aspect.width = 1;
365 pixel_mode.mode.cell_aspect.height = 1;
366 pixel_mode.mode.cell_visual.pixel_visual = visual;
367
368 link_initialize(&pixel_mode.link);
369 list_append(&pixel_mode.link, &vs->modes);
370
371 vs->def_mode_idx = 0;
372
373 vs->ops = kfb_ops;
374 vs->dev_ctx = NULL;
375
376 rc = ddf_fun_bind(fun_vs);
377 if (rc != EOK) {
378 list_remove(&pixel_mode.link);
379 ddf_fun_destroy(fun_vs);
380 as_area_destroy(kfb.addr);
381 return rc;
382 }
383
384 vs->reg_svc_handle = ddf_fun_get_handle(fun_vs);
385 ddf_fun_add_to_category(fun_vs, "visualizer");
386
387 return EOK;
388}
389
390/** @}
391 */
Note: See TracBrowser for help on using the repository browser.