00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <l4/sys/syscalls.h>
00018 #include <l4/l4rm/l4rm.h>
00019 #include <l4/env/errno.h>
00020 #include <l4/log/l4log.h>
00021 #include <l4/util/bitops.h>
00022 #include <l4/util/macros.h>
00023 #include <l4/dm_mem/dm_mem.h>
00024 #include <l4/dm_phys/dm_phys.h>
00025 #if defined(ARCH_x86) || defined(ARCH_amd64)
00026 #include <l4/util/rdtsc.h>
00027 #include <l4/util/idt.h>
00028 #endif
00029 #include <l4/generic_io/libio.h>
00030 #include "l4/l4con/l4con-server.h"
00031
00032
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036
00037
00038 #include "config.h"
00039 #include "gmode.h"
00040 #include "main.h"
00041 #include "pslim.h"
00042 #include "vc.h"
00043 #include "ev.h"
00044 #include "con_hw/fourcc.h"
00045 #include "con_hw/vidix.h"
00046 #include "con_yuv2rgb/yuv2rgb.h"
00047
00048 extern const char _binary_font_psf_start[];
00049 l4_umword_t status_area = 0;
00050
00051 static vidix_video_eq_t cscs_eq;
00052
00053 static int vc_open_in(struct l4con_vc*);
00054 static int vc_open_out(struct l4con_vc*);
00055
00056
00057 static void nothing_sync(void)
00058 {}
00059
00060 pslim_copy_fn fg_do_copy = sw_copy;
00061 pslim_copy_fn bg_do_copy = sw_copy;
00062 pslim_fill_fn fg_do_fill = sw_fill;
00063 pslim_fill_fn bg_do_fill = sw_fill;
00064 pslim_sync_fn fg_do_sync = nothing_sync;
00065 pslim_sync_fn bg_do_sync = nothing_sync;
00066 pslim_drty_fn fg_do_drty;
00067
00068 con_accel_t hw_accel =
00069 { copy:sw_copy, fill:sw_fill, sync:nothing_sync };
00070
00071
00072 static const l4con_pslim_color_t color_tab15[16] =
00073 {
00074 0x0000, 0x0015, 0x02a0, 0x02b5, 0x5400, 0x5415, 0x5540, 0x56b5,
00075 0x294a, 0x295f, 0x2bea, 0x2bff, 0x7d4a, 0x7d5f, 0x7fea, 0x7fff
00076 };
00077 static const l4con_pslim_color_t color_tab16[16] =
00078 {
00079 0x0000, 0x0015, 0x0540, 0x0555, 0xa800, 0xa815, 0xaaa0, 0xad55,
00080 0x52aa, 0x52bf, 0x57ea, 0x57ff, 0xfaaa, 0xfabf, 0xffea, 0xffff
00081 };
00082 static const l4con_pslim_color_t color_tab32[16] =
00083 {
00084 0x00000000, 0x000000aa, 0x0000aa00, 0x0000aaaa,
00085 0x00aa0000, 0x00aa00aa, 0x00aa5500, 0x00aaaaaa,
00086 0x00555555, 0x005555ff, 0x0055ff55, 0x0055ffff,
00087 0x00ff5555, 0x00ff55ff, 0x00ffff55, 0x00ffffff
00088 };
00089
00090
00091 static inline void
00092 convert_color(struct l4con_vc *vc, l4con_pslim_color_t *color)
00093 {
00094
00095 if ((*color & 0x80000000) == 0)
00096 {
00097 switch (vc->gmode & GRAPH_BPPMASK)
00098 {
00099 case GRAPH_BPP_24:
00100 case GRAPH_BPP_32:
00101 *color &= 0x00FFFFFF;
00102 break;
00103 case GRAPH_BPP_15:
00104 *color = (((*color >> (16 + 8 - VESA_RED_SIZE)) & ((1 << VESA_RED_SIZE)-1)) << VESA_RED_OFFS)
00105 | (((*color >> ( 8 + 8 - VESA_GREEN_SIZE)) & ((1 << VESA_GREEN_SIZE)-1)) << VESA_GREEN_OFFS)
00106 | (((*color >> ( 0 + 8 - VESA_BLUE_SIZE)) & ((1 << VESA_BLUE_SIZE)-1)) << VESA_BLUE_OFFS);
00107 break;
00108 case GRAPH_BPP_16:
00109 default:
00110 *color = ((*color & 0x00F80000) >> 8)
00111 | ((*color & 0x0000FC00) >> 5)
00112 | ((*color & 0x000000F8) >> 3);
00113 break;
00114 }
00115 }
00116 }
00117
00118 static int
00119 vc_l4io_init(void)
00120 {
00121 l4io_info_t *io_info_addr = (l4io_info_t*)0;
00122
00123 if (l4io_init(&io_info_addr, L4IO_DRV_INVALID))
00124 {
00125 Panic("Couldn't connect to L4 IO server!");
00126 return 1;
00127 }
00128 #ifndef ARCH_arm
00129 if (!io_info_addr->omega0)
00130 Panic("l4io has no omega0 mode enabled!");
00131 #endif
00132
00133 return 0;
00134 }
00135
00136
00137 static void
00138 vc_init_gr(void)
00139 {
00140 init_gmode();
00141
00142 switch(VESA_XRES)
00143 {
00144 case 800: VESA_RES = GRAPH_RES_800; break;
00145 case 1024: VESA_RES = GRAPH_RES_1024; break;
00146 case 1152: VESA_RES = GRAPH_RES_1152; break;
00147 case 1280: VESA_RES = GRAPH_RES_1280; break;
00148 case 1600: VESA_RES = GRAPH_RES_1600; break;
00149 case 640:
00150 default: VESA_RES = GRAPH_RES_640;
00151 }
00152
00153 switch(VESA_BITS)
00154 {
00155 case 15: VESA_RES |= GRAPH_BPP_15; break;
00156 case 16: VESA_RES |= GRAPH_BPP_16; break;
00157 case 24: VESA_RES |= GRAPH_BPP_24; break;
00158 case 32: VESA_RES |= GRAPH_BPP_32; break;
00159 }
00160
00161 yuv2rgb_init(VESA_BITS, MODE_RGB);
00162 }
00163
00164
00165 static int
00166 vc_font_init(void)
00167 {
00168
00169
00170 if (_binary_font_psf_start[0] != 0x36 || _binary_font_psf_start[1] != 0x04)
00171 Panic("psf magic number failed");
00172
00173 FONT_XRES = 8;
00174 FONT_YRES = _binary_font_psf_start[3];
00175
00176
00177 switch (_binary_font_psf_start[2])
00178 {
00179 case 0:
00180 case 2:
00181 FONT_CHRS = 256;
00182 break;
00183 case 1:
00184 case 3:
00185 FONT_CHRS = 512;
00186 break;
00187 default:
00188 Panic("bad psf font file magic %02x!", _binary_font_psf_start[2]);
00189 }
00190
00191 LOG_printf("Character size is %dx%d, font has %d characters\n",
00192 FONT_XRES, FONT_YRES, FONT_CHRS);
00193
00194 status_area = FONT_YRES + 4;
00195
00196 return 0;
00197 }
00198
00199 void
00200 vc_init()
00201 {
00202 int i;
00203
00204 vc_l4io_init();
00205 vc_font_init();
00206 vc_init_gr();
00207
00208 for (i = 0; i < MAX_NR_L4CONS; i++)
00209 {
00210
00211 vc[i] = malloc(sizeof(struct l4con_vc));
00212 if (!vc[i])
00213 {
00214 LOG_printf("Out of memory allocating l4con_vc");
00215 exit(-1);
00216 }
00217
00218
00219 vc[i]->prev = 0;
00220 vc[i]->next = 0;
00221 vc[i]->vc_number = i;
00222 vc[i]->mode = CON_CLOSED;
00223 vc[i]->vfb = 0;
00224 vc[i]->fb_lock = L4LOCK_UNLOCKED;
00225 }
00226
00227
00228 vc[0]->next =
00229 vc[0]->prev = vc[0];
00230 vc[0]->mode = CON_MASTER | CON_OUT;
00231 vc[0]->vfb = 0;
00232 vc[0]->vfb_in_server = 0;
00233 vc[0]->fb = gr_vmem;
00234 vc[0]->fb_mapped = 0;
00235 vc[0]->vc_partner_l4id = L4_INVALID_ID;
00236 vc[0]->vc_l4id = L4_INVALID_ID;
00237 vc[0]->ev_partner_l4id = L4_NIL_ID;
00238 vc[0]->gmode = VESA_RES;
00239 vc[0]->xres = VESA_XRES;
00240 vc[0]->yres = VESA_YRES;
00241 vc[0]->pan_xofs = pan_offs_x;
00242 vc[0]->pan_yofs = pan_offs_y;
00243 vc[0]->client_xofs = 0;
00244 vc[0]->client_yofs = 0;
00245 vc[0]->client_xres = VESA_XRES;
00246 vc[0]->client_yres = VESA_YRES_CLIENT;
00247 vc[0]->logo_x = 100000;
00248 vc[0]->logo_y = 100000;
00249 vc[0]->bpp = VESA_BITS;
00250 vc[0]->bytes_per_pixel = (VESA_BITS+7)/8;
00251 vc[0]->bytes_per_line = VESA_BPL;
00252 vc[0]->flags = accel_caps;
00253 vc[0]->do_sync = fg_do_sync;
00254 vc[0]->do_drty = fg_do_drty;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 static int
00266 vc_open(struct l4con_vc *vc, l4_uint8_t mode, l4_threadid_t ev_handler)
00267 {
00268 int error;
00269 l4_threadid_t e = L4_NIL_ID;
00270
00271 switch (mode)
00272 {
00273 case CON_INOUT:
00274 e = ev_handler;
00275
00276 if ((error = vc_open_in(vc)))
00277 return error;
00278
00279
00280
00281 case CON_OUT:
00282 vc->ev_partner_l4id = e;
00283
00284 if ((error = vc_open_out(vc)))
00285 return error;
00286
00287 vc->mode = mode;
00288
00289
00290 request_vc(vc->vc_number);
00291 break;
00292 }
00293
00294 return 0;
00295 }
00296
00297
00298
00299
00300
00301
00302 int
00303 vc_open_in(struct l4con_vc *vc)
00304 {
00305 l4_umword_t dummy;
00306 l4_msgdope_t result;
00307
00308
00309 if (l4_ipc_receive(vc->ev_partner_l4id, L4_IPC_SHORT_MSG, &dummy, &dummy,
00310 L4_IPC_RECV_TIMEOUT_0, &result) == L4_IPC_ENOT_EXISTENT)
00311 return -CON_ETHREAD;
00312
00313 return 0;
00314 }
00315
00316
00317
00318
00319
00320
00321 int
00322 vc_open_out(struct l4con_vc *vc)
00323 {
00324 int i;
00325
00326
00327 vc->gmode = VESA_RES;
00328 vc->client_xofs = 0;
00329 vc->client_yofs = 0;
00330 vc->client_xres = VESA_XRES;
00331 vc->client_yres = VESA_YRES_CLIENT;
00332 vc->xres = VESA_XRES;
00333 vc->yres = VESA_YRES;
00334 vc->pan_xofs = pan_offs_x;
00335 vc->pan_yofs = pan_offs_y;
00336 vc->bpp = VESA_BITS;
00337 vc->logo_x = 100000;
00338 vc->logo_y = 100000;
00339 vc->bytes_per_pixel = (vc->bpp+7)/8;
00340 vc->bytes_per_line = VESA_BPL;
00341 vc->vfb_size = ((vc->client_yres * vc->bytes_per_line) + 3) & ~3;
00342 vc->flags = accel_caps;
00343 vc->do_copy = bg_do_copy;
00344 vc->do_fill = bg_do_fill;
00345 vc->do_sync = bg_do_sync;
00346 vc->do_drty = 0;
00347
00348 for (i=0; i<CONFIG_MAX_CLIENTS; i++)
00349 vc->clients[i] = L4_INVALID_ID;
00350
00351 switch (vc->gmode & GRAPH_BPPMASK)
00352 {
00353 case GRAPH_BPP_32:
00354 case GRAPH_BPP_24: vc->color_tab = color_tab32; break;
00355 case GRAPH_BPP_15: vc->color_tab = color_tab15; break;
00356 case GRAPH_BPP_16:
00357 default: vc->color_tab = color_tab16; break;
00358 }
00359
00360 if (vc->vfb_in_server)
00361 {
00362 int error;
00363 char ds_name[32];
00364 l4dm_dataspace_t ds;
00365
00366 sprintf(ds_name, "vfb for "l4util_idfmt,
00367 l4util_idstr(vc->vc_partner_l4id));
00368 if ((error = l4dm_mem_open(L4DM_DEFAULT_DSM, vc->vfb_size,
00369 0, 0, ds_name, &ds)))
00370 {
00371 LOG("Error %d requesting %d bytes for vc", error, vc->vfb_size);
00372 Panic("open_vc_out");
00373 return -CON_ENOMEM;
00374 }
00375 if ((error = l4rm_attach(&ds, vc->vfb_size, 0,
00376 L4DM_RW | L4RM_SUPERPAGE_ALIGNED,
00377 (void**)&vc->vfb)))
00378 {
00379 LOG("Error %d attaching vc dataspace", error);
00380 Panic("open_vc_out");
00381 }
00382
00383 memset(vc->vfb, 0, vc->vfb_size);
00384 vc->fb = vc->vfb;
00385 vc->pan_xofs = 0;
00386 vc->pan_yofs = 0;
00387 }
00388
00389 LOG_printf("vc[%d] %ldx%ld@%d, bpl:%ld, gmode:0x%x, evprt:"l4util_idfmt
00390 " save:%d\n", vc->vc_number, vc->xres, vc->yres, vc->bpp,
00391 vc->bytes_per_line, vc->gmode, l4util_idstr(vc->ev_partner_l4id),
00392 vc->save_restore);
00393 return 0;
00394 }
00395
00396
00397
00398
00399
00400
00401 int
00402 vc_close(struct l4con_vc *this_vc)
00403 {
00404
00405
00406
00407 l4lock_lock(&this_vc->fb_lock);
00408
00409 this_vc->mode = CON_CLOSING;
00410 if (this_vc->vfb_in_server && this_vc->vfb)
00411 {
00412 l4dm_mem_release(this_vc->vfb);
00413 this_vc->vfb = 0;
00414 }
00415 this_vc->vfb_in_server = 0;
00416 this_vc->fb = 0;
00417 l4lock_unlock(&this_vc->fb_lock);
00418
00419 if (this_vc->sbuf1)
00420 {
00421 l4dm_mem_release(this_vc->sbuf1);
00422 this_vc->sbuf1 = 0;
00423 }
00424 if (this_vc->sbuf2)
00425 {
00426 l4dm_mem_release(this_vc->sbuf2);
00427 this_vc->sbuf2 = 0;
00428 }
00429 if (this_vc->sbuf3)
00430 {
00431 l4dm_mem_release(this_vc->sbuf3);
00432 this_vc->sbuf3 = 0;
00433 }
00434
00435 this_vc->ev_partner_l4id = L4_NIL_ID;
00436
00437 if (this_vc->vc_number == fg_vc)
00438 request_vc(-1);
00439 else
00440 update_id = 1;
00441
00442 return 0;
00443 }
00444
00445
00446
00447 static int
00448 vc_puts(struct l4con_vc *vc, int from_user,
00449 const char *str, int len, l4_int16_t x, l4_int16_t y,
00450 l4con_pslim_color_t fg_color, l4con_pslim_color_t bg_color)
00451 {
00452 int i, j;
00453
00454 convert_color(vc, &fg_color);
00455 convert_color(vc, &bg_color);
00456
00457 if(vc->fb == 0)
00458 return 0;
00459
00460 for (i=0; i<len; i++, str++)
00461 {
00462
00463 for (j=0; (i<len) && (*str == ' '); i++, j++, str++)
00464 ;
00465
00466 if (j>0)
00467 {
00468 l4con_pslim_rect_t rect = { x, y, j*FONT_XRES, FONT_YRES };
00469
00470 pslim_fill(vc, from_user, &rect, bg_color);
00471 x += j*FONT_XRES;
00472 i--; str--;
00473 }
00474 else
00475 {
00476 l4con_pslim_rect_t rect = { x, y, FONT_XRES, FONT_YRES };
00477
00478 pslim_bmap(vc, from_user, &rect, fg_color, bg_color,
00479 (void*) &_binary_font_psf_start[rect.h * (*str)+4],
00480 pSLIM_BMAP_START_MSB);
00481 x += FONT_XRES;
00482 }
00483 }
00484
00485 return 0;
00486 }
00487
00488
00489
00490 static int
00491 vc_fill(struct l4con_vc *vc, int from_user,
00492 l4con_pslim_rect_t *rect, l4con_pslim_color_t color)
00493 {
00494 if (!(vc->mode & CON_OUT))
00495 return -CON_EPERM;
00496
00497 convert_color(vc, &color);
00498
00499 if (vc->fb != 0)
00500 pslim_fill(vc, from_user, rect, color);
00501
00502 return 0;
00503 }
00504
00505
00506
00507 static int
00508 vc_puts_scale(struct l4con_vc *vc, int from_user,
00509 const char *str, int len, l4_int16_t x, l4_int16_t y,
00510 l4con_pslim_color_t fg_color, l4con_pslim_color_t bg_color,
00511 int scale_x, int scale_y)
00512 {
00513 int pix_x, pix_y;
00514 l4con_pslim_rect_t rect = { x, y, FONT_XRES*scale_x, FONT_YRES*scale_y };
00515
00516 pix_x = scale_x;
00517 if (scale_x >= 5)
00518 pix_x = scale_x * 14/15;
00519 pix_y = scale_y;
00520 if (scale_y >= 5)
00521 pix_y = scale_y * 14/15;
00522
00523 convert_color(vc, &fg_color);
00524 convert_color(vc, &bg_color);
00525
00526 if(vc->fb != 0)
00527 {
00528 int i;
00529 for (i=0; i<len; i++, str++)
00530 {
00531 l4con_pslim_rect_t lrect = { rect.x, rect.y, pix_x, pix_y };
00532 const char *bmap = &_binary_font_psf_start[FONT_YRES*(*str) + 4];
00533 int j;
00534
00535 for (j=0; j<FONT_YRES; j++)
00536 {
00537 unsigned char mask = 0x80;
00538 int k;
00539
00540 for (k=0; k<FONT_XRES; k++)
00541 {
00542 l4con_pslim_color_t color = (*bmap & mask) ? fg_color
00543 : bg_color;
00544 pslim_fill(vc, from_user, &lrect, color);
00545 lrect.x += scale_x;
00546 bmap += (mask & 1);
00547 mask = (mask >> 1) | (mask << 7);
00548 }
00549 lrect.x -= rect.w;
00550 lrect.y += scale_y;
00551 }
00552 rect.x += rect.w;
00553 }
00554 }
00555
00556 return 0;
00557 }
00558
00559
00560
00561 void
00562 vc_show_id(struct l4con_vc *this_vc)
00563 {
00564 char id[64];
00565 int i, x, cnt_vc;
00566 const l4con_pslim_color_t fgc = 0x009999FF;
00567 const l4con_pslim_color_t bgc = 0x00666666;
00568 l4con_pslim_rect_t rect = { 0, this_vc->client_yres,
00569 this_vc->xres, status_area };
00570
00571 cnt_vc = MAX_NR_L4CONS > 10 ? 9 : MAX_NR_L4CONS-1;
00572
00573 vc_fill(this_vc, 0, &rect, bgc);
00574
00575 if (this_vc->vc_number != 0)
00576 sprintf(id, "TUDOS console: partner "l4util_idfmt" ",
00577 l4util_idstr(this_vc->vc_partner_l4id));
00578 else
00579 strcpy(id, "TUDOS console: (all closed)");
00580
00581 vc_puts(this_vc, 0, id, strlen(id), 2, this_vc->client_yres+2, fgc, bgc);
00582
00583 sprintf(id, "%ldx%ld@%d%s%s",
00584 this_vc->xres, this_vc->yres, this_vc->bpp,
00585 panned ? " [PAN]" : "",
00586 this_vc->fb_mapped ? " [FBmap]" : "");
00587 vc_puts(this_vc, 0, id, strlen(id),
00588 ((this_vc->xres - strlen(id)*FONT_XRES) / 2), this_vc->client_yres+2,
00589 fgc, bgc);
00590
00591 for (i=1, x=this_vc->xres-cnt_vc*(FONT_XRES+2);
00592 i<=cnt_vc;
00593 i++, x+=FONT_XRES+2)
00594 {
00595 int _fgc = 0x00000000, _bgc = bgc, tmp;
00596
00597 if (vc[i]->mode == CON_INOUT || vc[i]->mode == CON_OUT)
00598 _fgc = 0x0000FF00;
00599
00600 if (this_vc == vc[i])
00601 {
00602 tmp = _fgc; _fgc = _bgc; _bgc = tmp;
00603 }
00604
00605 id[0] = '0' + i;
00606
00607 vc_puts(this_vc, 0, id, 1, x, this_vc->yres-FONT_YRES-2, _fgc, _bgc);
00608 }
00609 }
00610
00611 void
00612 vc_show_dmphys_poolsize(struct l4con_vc *this_vc)
00613 {
00614 const l4con_pslim_color_t fgc = 0x009999FF;
00615 const l4con_pslim_color_t bgc = 0x00666666;
00616 char str[32];
00617 l4_size_t size, free;
00618
00619 l4dm_memphys_poolsize(L4DM_MEMPHYS_DEFAULT, &size, &free);
00620 l4con_pslim_rect_t rect =
00621 { this_vc->xres - 180, this_vc->client_yres, 80, status_area };
00622 vc_fill(this_vc, 0, &rect, bgc);
00623 sprintf(str, "%3zd/%zdMB", free/(1<<20), size/(1<<20));
00624 vc_puts(this_vc, 0, str, strlen(str), rect.x, rect.y+2, fgc, bgc);
00625 }
00626
00627 #if defined(ARCH_x86) || defined(ARCH_amd64)
00628 static void
00629 show_counters(struct l4con_vc *this_vc)
00630 {
00631 #if 0
00632 l4_tracebuffer_status_t *tb = fiasco_tbuf_get_status();
00633
00634 l4con_pslim_rect_t rect = { this_vc->xres-380, this_vc->client_yres,
00635 14*8, status_area };
00636
00637 char str[32];
00638 const l4con_pslim_color_t fgc = 0x009999FF;
00639 const l4con_pslim_color_t bgc = 0x00666666;
00640
00641 vc_fill(this_vc, 0, &rect, bgc);
00642 sprintf(str, "%6ld %6ld", tb->cnt_context_switch, tb->cnt_addr_space_switch);
00643 vc_puts(this_vc, 0, str, strlen(str), rect.x, rect.y+2, fgc, bgc);
00644 #endif
00645 }
00646 #endif
00647
00648 #if defined(ARCH_x86) || defined(ARCH_amd64)
00649 static void
00650 vc_show_history(struct l4con_vc *this_vc,
00651 l4_uint8_t *history_val, l4_size_t history_size,
00652 l4con_pslim_color_t fgc, l4con_pslim_color_t bgc,
00653 l4con_pslim_rect_t *rect)
00654 {
00655
00656 int i, j;
00657 l4_uint8_t b;
00658 l4_uint8_t history_map[history_size/8*status_area];
00659
00660 convert_color(this_vc, &fgc);
00661 convert_color(this_vc, &bgc);
00662
00663 for (i=0, b=0x80; i<history_size; i++, b = (b>>1)|(b<<7))
00664 {
00665 for (j=0; j<status_area; j++)
00666 if (history_val[i] >= status_area-j)
00667 history_map[i/8 + history_size/8*j] |= b;
00668 else
00669 history_map[i/8 + history_size/8*j] &= ~b;
00670 }
00671 pslim_bmap(this_vc, 0, rect, fgc, bgc, history_map, pSLIM_BMAP_START_MSB);
00672 }
00673 #endif
00674
00675 void
00676 vc_show_cpu_load(struct l4con_vc *this_vc)
00677 {
00678 #if defined(ARCH_x86) || defined(ARCH_amd64)
00679 static l4_uint32_t tsc, pmc;
00680 static l4_uint8_t history_val[6*8];
00681 l4_uint32_t new_tsc = l4_rdtsc_32(), new_pmc = l4_rdpmc_32(0);
00682 l4con_pslim_rect_t rect = { this_vc->xres-260, this_vc->client_yres,
00683 sizeof(history_val), status_area };
00684
00685 memmove(history_val, history_val+1, sizeof(history_val)-1);
00686
00687 show_counters(this_vc);
00688
00689 if (!tsc || !pmc)
00690 history_val[sizeof(history_val)-1] = 0;
00691
00692 else
00693 {
00694 history_val[sizeof(history_val)-1] = (new_pmc-pmc) /
00695 ((new_tsc-tsc)/status_area);
00696
00697 if (cpu_load_history == 0)
00698 {
00699
00700 char str[16];
00701 const l4con_pslim_color_t fgc = 0x009999FF;
00702 const l4con_pslim_color_t bgc = 0x00666666;
00703
00704 l4_uint32_t load = (new_pmc-pmc) / ((new_tsc-tsc)/1000);
00705 vc_fill(this_vc, 0, &rect, bgc);
00706 if (load > 1000)
00707 strcpy(str, "---.-%");
00708 else
00709 sprintf(str, "%3d.%d%%", load/10, load % 10);
00710 vc_puts(this_vc, 0, str, strlen(str), rect.x, rect.y+2, fgc, bgc);
00711 }
00712 else
00713 vc_show_history(this_vc, history_val, sizeof(history_val),
00714 0x00CC5555, 0x00222222, &rect);
00715 }
00716
00717 tsc = new_tsc;
00718 pmc = new_pmc;
00719 #endif
00720 }
00721
00722 void
00723 vc_show_drops_cscs_logo(void)
00724 {
00725 if (vc[fg_vc]->logo_x != 100000)
00726 {
00727 static l4con_pslim_color_t color = 0x00050505;
00728 static l4con_pslim_color_t adder = 0x00050301;
00729
00730 color += adder;
00731 if (color > 0x00f0f0f0)
00732 adder = -adder;
00733 else if (color < 0x00050505)
00734 adder = -adder;
00735
00736 vc_puts_scale(vc[fg_vc], 0, "DROPS", 5,
00737 vc[fg_vc]->logo_x, vc[fg_vc]->logo_y,
00738 color, 0x00ff00ff, 1, 2);
00739 }
00740 }
00741
00742
00743
00744 void
00745 vc_clear(struct l4con_vc *vc)
00746 {
00747 const l4con_pslim_color_t fgc = 0x00223344;
00748 const l4con_pslim_color_t bgc = 0x00000000;
00749 l4con_pslim_rect_t rect = { 0, 0, vc->client_xres, vc->client_yres };
00750
00751 vc_fill(vc, 0, &rect, bgc);
00752
00753
00754 if (vc->vc_number == 0)
00755 {
00756
00757 int x, y, scale_x_1, scale_y_1, scale_x_2, scale_y_2;
00758
00759 scale_x_1 = (vc->client_xres*4/ 5) / (5*FONT_XRES);
00760 scale_y_1 = (vc->client_yres*6/10) / (1*FONT_YRES);
00761 x = vc->client_xofs + (vc->client_xres-5*FONT_XRES*scale_x_1)/2;
00762 y = vc->client_yofs + (vc->client_yres-1*FONT_YRES*scale_y_1)*3/7;
00763 vc_puts_scale(vc, 0,
00764 "TUDOS", 5,
00765 x, y, fgc, bgc, scale_x_1, scale_y_1);
00766 scale_x_2 = scale_x_1*10/90;
00767 scale_y_2 = scale_y_1*10/90;
00768 x = vc->client_xofs + (vc->client_xres-36*FONT_XRES*scale_x_2)/2;
00769 y += 1*FONT_YRES*scale_y_1*12/14;
00770 vc_puts_scale(vc, 0,
00771 "The Dresden Operating System Project", 36,
00772 x, y, fgc, bgc, scale_x_2, scale_y_2);
00773 }
00774 }
00775
00776
00777
00778 long
00779 con_vc_smode_component (CORBA_Object _dice_corba_obj,
00780 unsigned char mode,
00781 const l4_threadid_t *ev_handler,
00782 CORBA_Server_Environment *_dice_corba_env)
00783 {
00784 struct l4con_vc *vc = (struct l4con_vc*)(_dice_corba_env->user_data);
00785
00786 if (vc->mode == CON_OPENING)
00787 {
00788
00789 vc->ev_partner_l4id = *ev_handler;
00790 return vc_open(vc, mode & CON_INOUT, *ev_handler);
00791 }
00792 else
00793 {
00794
00795 vc->ev_partner_l4id = mode & CON_IN ? *ev_handler : L4_NIL_ID;
00796 return 0;
00797 }
00798 }
00799
00800
00801
00802 long
00803 con_vc_gmode_component (CORBA_Object _dice_corba_obj,
00804 unsigned char *mode,
00805 unsigned long *sbuf_1size,
00806 unsigned long *sbuf_2size,
00807 unsigned long *sbuf_3size,
00808 CORBA_Server_Environment *_dice_corba_env)
00809 {
00810 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
00811
00812 *mode = vc->mode;
00813 *sbuf_1size = vc->sbuf1_size;
00814 *sbuf_2size = vc->sbuf2_size;
00815 *sbuf_3size = vc->sbuf3_size;
00816
00817 return 0;
00818 }
00819
00820 long
00821 con_vc_share_component (CORBA_Object _dice_corba_obj,
00822 const l4_threadid_t *client,
00823 CORBA_Server_Environment *_dice_corba_env)
00824 {
00825 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
00826 int i;
00827
00828 for (i=0; i<CONFIG_MAX_CLIENTS; i++)
00829 if (l4_thread_equal(*client, vc->clients[i]))
00830 return 0;
00831 else if (l4_is_invalid_id(vc->clients[i]))
00832 {
00833 vc->clients[i] = *client;
00834 return 0;
00835 }
00836
00837 return -L4_ENOSPC;
00838 }
00839
00840 long
00841 con_vc_revoke_component (CORBA_Object _dice_corba_obj,
00842 const l4_threadid_t *client,
00843 CORBA_Server_Environment *_dice_corba_env)
00844 {
00845 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
00846 int i;
00847
00848 for (i=0; i<CONFIG_MAX_CLIENTS; i++)
00849 if (l4_thread_equal(*client, vc->clients[i]))
00850 {
00851 vc->clients[i] = L4_INVALID_ID;
00852 return 0;
00853 }
00854
00855 return -L4_ENOTFOUND;
00856 }
00857
00858
00859
00860 long
00861 con_vc_close_component(CORBA_Object _dice_corba_obj,
00862 l4_int16_t *_dice_reply,
00863 CORBA_Server_Environment *_dice_corba_env)
00864 {
00865 long ret;
00866 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
00867
00868 ret = vc_close(vc);
00869 if (vc->mode == CON_CLOSING)
00870 {
00871
00872 vc->mode = CON_CLOSED;
00873
00874
00875 con_vc_close_reply(_dice_corba_obj, ret, _dice_corba_env);
00876
00877
00878
00879
00880 l4thread_exit();
00881 }
00882
00883
00884
00885 return ret;
00886 }
00887
00888
00889
00890 long
00891 con_vc_graph_smode_component(CORBA_Object _dice_corba_obj,
00892 l4_uint8_t g_mode,
00893 CORBA_Server_Environment *_dice_corba_env)
00894 {
00895 return -CON_ENOTIMPL;
00896 }
00897
00898
00899
00900 long
00901 con_vc_graph_gmode_component(CORBA_Object _dice_corba_obj,
00902 l4_uint8_t *g_mode,
00903 l4_uint32_t *xres,
00904 l4_uint32_t *yres,
00905 l4_uint32_t *bits_per_pixel,
00906 l4_uint32_t *bytes_per_pixel,
00907 l4_uint32_t *bytes_per_line,
00908 l4_uint32_t *flags,
00909 l4_uint32_t *xtxt,
00910 l4_uint32_t *ytxt,
00911 CORBA_Server_Environment *_dice_corba_env)
00912 {
00913 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
00914
00915 *g_mode = vc->gmode;
00916 *xres = vc->client_xres;
00917 *yres = vc->client_yres;
00918 *bits_per_pixel = vc->bpp;
00919 *bytes_per_pixel = vc->bytes_per_pixel;
00920 *bytes_per_line = vc->bytes_per_line;
00921 *flags = vc->flags;
00922 *xtxt = FONT_XRES;
00923 *ytxt = FONT_YRES;
00924 return 0;
00925 }
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938 long
00939 con_vc_graph_get_rgb_component(CORBA_Object _dice_corba_obj,
00940 l4_uint32_t *red_offs,
00941 l4_uint32_t *red_len,
00942 l4_uint32_t *green_offs,
00943 l4_uint32_t *green_len,
00944 l4_uint32_t *blue_offs,
00945 l4_uint32_t *blue_len,
00946 CORBA_Server_Environment *_dice_corba_env)
00947 {
00948 *red_offs = VESA_RED_OFFS;
00949 *red_len = VESA_RED_SIZE;
00950 *green_offs = VESA_GREEN_OFFS;
00951 *green_len = VESA_GREEN_SIZE;
00952 *blue_offs = VESA_BLUE_OFFS;
00953 *blue_len = VESA_BLUE_SIZE;
00954
00955 return 0;
00956 }
00957
00958 long
00959 con_vc_graph_mapfb_component(CORBA_Object _dice_corba_obj,
00960 unsigned long fb_offset,
00961 l4_snd_fpage_t *page,
00962 unsigned long *page_offset,
00963 CORBA_Server_Environment *_dice_corba_env)
00964 {
00965 struct l4con_vc *this_vc = (struct l4con_vc *)(_dice_corba_env->user_data);
00966 l4_addr_t base = l4_trunc_superpage(vis_vmem);
00967 l4_offs_t offs = (l4_addr_t)vis_vmem - base;
00968
00969
00970 *page_offset = fb_offset == 0 ? offs : 0;
00971
00972 l4lock_lock(&want_vc_lock);
00973
00974
00975 if (!l4_tasknum_equal(*_dice_corba_obj, vc_partner_l4id))
00976 {
00977
00978 int i;
00979
00980 for (i=0; i<CONFIG_MAX_CLIENTS; i++)
00981 if (l4_tasknum_equal(*_dice_corba_obj, vc[fg_vc]->clients[i]))
00982 break;
00983
00984 if (i >= CONFIG_MAX_CLIENTS)
00985 {
00986
00987
00988
00989 int msg_first = 1;
00990 LOG_printf("mapfb: not allowed to map FB. Currently allowed: ");
00991 for (i=0; i<CONFIG_MAX_CLIENTS; i++)
00992 {
00993 if (!l4_is_invalid_id(vc[fg_vc]->clients[i]))
00994 {
00995 if (msg_first)
00996 {
00997 LOG_printf("\n");
00998 msg_first = 0;
00999 }
01000 LOG_printf(" "l4util_idfmt"\n", l4util_idstr(vc[fg_vc]->clients[i]));
01001 }
01002 }
01003 if (msg_first)
01004 LOG_printf("None.\n");
01005 page->snd_base = 0;
01006 page->fpage.raw = 0;
01007 l4lock_unlock(&want_vc_lock);
01008 return -L4_EPERM;
01009 }
01010 }
01011
01012 if ((gr_vmem + fb_offset + L4_SUPERPAGESIZE > gr_vmem_maxmap) ||
01013 (fb_offset % L4_SUPERPAGESIZE))
01014 {
01015
01016
01017 page->snd_base = 0;
01018 page->fpage.raw = 0;
01019 l4lock_unlock(&want_vc_lock);
01020 return -L4_EINVAL_OFFS;
01021 }
01022
01023 page->snd_base = 0;
01024 page->fpage = l4_fpage(base+fb_offset, L4_LOG2_SUPERPAGESIZE,
01025 L4_FPAGE_RW, L4_FPAGE_MAP);
01026 this_vc->fb_mapped = 1;
01027 update_id = 1;
01028
01029 l4lock_unlock(&want_vc_lock);
01030
01031 return 0;
01032 }
01033
01034
01035 long
01036 con_vc_ev_sflt_component(CORBA_Object _dice_corba_obj,
01037 unsigned long filter,
01038 CORBA_Server_Environment *_dice_corba_env)
01039 {
01040 return -CON_ENOTIMPL;
01041 }
01042
01043 long
01044 con_vc_ev_gflt_component(CORBA_Object _dice_corba_obj,
01045 unsigned long *filter,
01046 CORBA_Server_Environment *_dice_corba_env)
01047 {
01048 return -CON_ENOTIMPL;
01049 }
01050
01051
01052
01053 long
01054 con_vc_pslim_fill_component(CORBA_Object _dice_corba_obj,
01055 const l4con_pslim_rect_t *rect,
01056 l4con_pslim_color_t color,
01057 CORBA_Server_Environment *_dice_corba_env)
01058 {
01059 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
01060
01061
01062 l4lock_lock(&vc->fb_lock);
01063 vc_fill(vc, 1, (l4con_pslim_rect_t*)rect, color);
01064
01065
01066 if (vc->fb_mapped)
01067 vc->do_sync();
01068 l4lock_unlock(&vc->fb_lock);
01069
01070 return 0;
01071 }
01072
01073
01074
01075 long
01076 con_vc_pslim_copy_component(CORBA_Object _dice_corba_obj,
01077 const l4con_pslim_rect_t *rect,
01078 l4_int16_t dx,
01079 l4_int16_t dy,
01080 CORBA_Server_Environment *_dice_corba_env)
01081 {
01082 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
01083
01084 if ((vc->mode & CON_OUT)==0)
01085 return -CON_EPERM;
01086
01087
01088 l4lock_lock(&vc->fb_lock);
01089 if(vc->fb != 0)
01090 pslim_copy(vc, 1, (l4con_pslim_rect_t*)rect, dx, dy);
01091
01092
01093 if (vc->fb_mapped)
01094 vc->do_sync();
01095 l4lock_unlock(&vc->fb_lock);
01096
01097 return 0;
01098 }
01099
01100
01101
01102
01103 long
01104 con_vc_pslim_bmap_component(CORBA_Object _dice_corba_obj,
01105 const l4con_pslim_rect_t *rect,
01106 l4con_pslim_color_t fg_color,
01107 l4con_pslim_color_t bg_color,
01108 const l4_uint8_t* bmap,
01109 long bmap_size,
01110 l4_uint8_t bmap_type,
01111 CORBA_Server_Environment *_dice_corba_env)
01112 {
01113 void *map = (void*)bmap;
01114 struct l4con_vc *this_vc = (struct l4con_vc*)(_dice_corba_env->user_data);
01115
01116 if ((this_vc->mode & CON_OUT)==0)
01117 return -CON_EPERM;
01118
01119 convert_color(this_vc, &fg_color);
01120 convert_color(this_vc, &bg_color);
01121
01122
01123 l4lock_lock(&this_vc->fb_lock);
01124 if (this_vc->fb != 0)
01125 pslim_bmap(this_vc, 1, (l4con_pslim_rect_t*)rect,
01126 fg_color, bg_color, map, bmap_type);
01127 l4lock_unlock(&this_vc->fb_lock);
01128
01129 return 0;
01130 }
01131
01132
01133
01134 long
01135 con_vc_pslim_set_component(CORBA_Object _dice_corba_obj,
01136 const l4con_pslim_rect_t *rect,
01137 const l4_uint8_t* pmap,
01138 long pmap_size,
01139 CORBA_Server_Environment *_dice_corba_env)
01140 {
01141 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
01142 void *map = (void*)pmap;
01143
01144 if ((vc->mode & CON_OUT)==0)
01145 return -CON_EPERM;
01146
01147
01148 l4lock_lock(&vc->fb_lock);
01149 if(vc->fb != 0)
01150 pslim_set(vc, 1, (l4con_pslim_rect_t*)rect, map);
01151 l4lock_unlock(&vc->fb_lock);
01152
01153 return 0;
01154 }
01155
01156
01157
01158
01159 long
01160 con_vc_pslim_cscs_component (CORBA_Object _dice_corba_obj,
01161 const l4con_pslim_rect_t *rect,
01162 const unsigned char *y,
01163 int y_l,
01164 const unsigned char *u,
01165 int u_l,
01166 const unsigned char *v,
01167 int v_l,
01168 long yuv_type,
01169 char scale,
01170 CORBA_Server_Environment *_dice_corba_env)
01171 {
01172 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
01173
01174 if ((vc->mode & CON_OUT)==0)
01175 return -CON_EPERM;
01176
01177 if (scale != 1)
01178 return -CON_ENOTIMPL;
01179
01180
01181 l4lock_lock(&vc->fb_lock);
01182 if(vc->fb != 0)
01183 {
01184 switch (yuv_type)
01185 {
01186 case pSLIM_CSCS_PLN_I420:
01187 pslim_cscs(vc, 1, (l4con_pslim_rect_t*)rect,
01188 (void*)y, (void*)v, (void*)u,
01189 yuv_type, 1);
01190 break;
01191 case pSLIM_CSCS_PLN_YV12:
01192 pslim_cscs(vc, 1, (l4con_pslim_rect_t*)rect,
01193 (void*)y, (void*)u, (void*)v,
01194 yuv_type, 1);
01195 break;
01196 }
01197 }
01198 l4lock_unlock(&vc->fb_lock);
01199
01200 return 0;
01201 }
01202
01203
01204
01205 long
01206 con_vc_puts_component (CORBA_Object _dice_corba_obj,
01207 const char *s,
01208 int len,
01209 short x,
01210 short y,
01211 l4con_pslim_color_t fg_color,
01212 l4con_pslim_color_t bg_color,
01213 CORBA_Server_Environment *_dice_corba_env)
01214 {
01215 long ret;
01216 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
01217
01218 l4lock_lock(&vc->fb_lock);
01219 ret = vc_puts(vc, 1, s, len, x, y, fg_color, bg_color);
01220 l4lock_unlock(&vc->fb_lock);
01221
01222 return ret;
01223 }
01224
01225
01226
01227 long
01228 con_vc_puts_scale_component(CORBA_Object _dice_corba_obj,
01229 const char *s,
01230 int len,
01231 short x,
01232 short y,
01233 l4con_pslim_color_t fg_color,
01234 l4con_pslim_color_t bg_color,
01235 short scale_x,
01236 short scale_y,
01237 CORBA_Server_Environment *_dice_corba_env)
01238 {
01239 long ret;
01240 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
01241
01242 l4lock_lock(&vc->fb_lock);
01243 ret = vc_puts_scale(vc, 1, s, len, x, y, fg_color, bg_color, scale_x, scale_y);
01244 l4lock_unlock(&vc->fb_lock);
01245
01246 return ret;
01247 }
01248
01249
01250
01251 long
01252 con_vc_puts_attr_component (CORBA_Object _dice_corba_obj,
01253 const short *s,
01254 int strattr_size,
01255 short x,
01256 short y,
01257 CORBA_Server_Environment *_dice_corba_env)
01258 {
01259 int i, j;
01260 l4_uint16_t* str = (l4_uint16_t*) s;
01261
01262 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
01263
01264 l4lock_lock(&vc->fb_lock);
01265 if(vc->fb != 0)
01266 {
01267 for(i=0; i<strattr_size; i+=2)
01268 {
01269 const int c = *str++;
01270 const l4con_pslim_color_t fgc = vc->color_tab[(c & 0x0F00) >> 8];
01271 const l4con_pslim_color_t bgc = vc->color_tab[(c & 0xF000) >> 12];
01272
01273 if ((c & 0xFF) == ' ')
01274 {
01275
01276 l4con_pslim_rect_t rect;
01277
01278 for (j=1; (*str == c) && (i<strattr_size-2); i+=2, j++, str++)
01279 ;
01280 rect = (l4con_pslim_rect_t) { x, y, j*FONT_XRES, FONT_YRES };
01281 pslim_fill(vc, 1, &rect, bgc);
01282 x += j*FONT_XRES;
01283 }
01284 else
01285 {
01286 l4con_pslim_rect_t rect = { x, y, FONT_XRES, FONT_YRES };
01287
01288 pslim_bmap(vc, 1,
01289 &rect, fgc, bgc,
01290 (void*)&_binary_font_psf_start[rect.h * (c & 0xFF)+4],
01291 pSLIM_BMAP_START_MSB);
01292 x += FONT_XRES;
01293 }
01294 }
01295 }
01296
01297
01298 if (vc->fb_mapped)
01299 vc->do_sync();
01300 l4lock_unlock(&vc->fb_lock);
01301 return 0;
01302 }
01303
01304
01305 long
01306 con_vc_direct_update_component(CORBA_Object _dice_corba_obj,
01307 const l4con_pslim_rect_t *rect,
01308 CORBA_Server_Environment *_dice_corba_env)
01309 {
01310 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
01311
01312 if ((vc->mode & CON_OUT)==0)
01313 return -CON_EPERM;
01314
01315 if (vc->fb_mapped)
01316 {
01317 if (hw_accel.caps & ACCEL_POST_DIRTY)
01318 {
01319
01320 if (vc->do_drty)
01321 vc->do_drty(rect->x, rect->y, rect->w, rect->h);
01322 return 0;
01323 }
01324 else
01325 {
01326 static int bug;
01327 if (!bug)
01328 {
01329 LOG_printf("fb mapped and post dirty probably not necessary "
01330 "by "l4util_idfmt"\n", l4util_idstr(*_dice_corba_obj));
01331 bug++;
01332 }
01333 }
01334 }
01335
01336 if (vc->vfb == 0)
01337 {
01338 LOG_printf("no vfb set\n");
01339 return -CON_EPERM;
01340 }
01341
01342
01343 l4lock_lock(&vc->fb_lock);
01344 if(vc->fb != 0)
01345 pslim_set(vc, 1, (l4con_pslim_rect_t*)rect, 0 );
01346 l4lock_unlock(&vc->fb_lock);
01347
01348 return 0;
01349 }
01350
01351
01352 long
01353 con_vc_direct_setfb_component(CORBA_Object _dice_corba_obj,
01354 const l4dm_dataspace_t *data_ds,
01355 CORBA_Server_Environment *_dice_corba_env)
01356 {
01357 int error;
01358 l4_size_t size;
01359
01360 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
01361
01362 if (vc->vfb_in_server)
01363 {
01364 LOG("Virtual framebuffer allocated by server -- direct_setfb nonsense");
01365 return -L4_EINVAL;
01366 }
01367
01368 if (vc->vfb)
01369 {
01370 LOG("Virtual framebuffer already mapped -- direct_setfb nonsense");
01371 return -L4_EINVAL;
01372 }
01373
01374 if ((error = l4dm_mem_size((l4dm_dataspace_t*)data_ds, &size)))
01375 {
01376 LOG("Error %d requesting size of data_ds", error);
01377 return -L4_EINVAL;
01378 }
01379
01380 if ((error = l4rm_attach((l4dm_dataspace_t*)data_ds, size, 0,
01381 L4DM_RO | L4RM_MAP | L4RM_SUPERPAGE_ALIGNED,
01382 (void*)&vc->vfb)))
01383 {
01384 LOG("Error %d attaching data_ds", error);
01385 return -L4_EINVAL;
01386 }
01387
01388 LOG_printf("Mapped client FB to %08lx size %08zx\n",
01389 (l4_addr_t)vc->vfb, size);
01390
01391 return 0;
01392 }
01393
01394
01395
01396
01397 long
01398 con_vc_stream_cscs_component(CORBA_Object _dice_corba_obj,
01399 const l4con_pslim_rect_t *rect_src,
01400 const l4con_pslim_rect_t *rect_dst,
01401 l4_uint8_t yuv_type,
01402 l4_snd_fpage_t *buffer,
01403 unsigned long *offs_y,
01404 unsigned long *offs_u,
01405 unsigned long *offs_v,
01406 CORBA_Server_Environment *_dice_corba_env)
01407 {
01408 struct l4con_vc *vc = (struct l4con_vc *)(_dice_corba_env->user_data);
01409 vidix_playback_t config;
01410
01411 if (!hw_accel.caps & ACCEL_FAST_CSCS)
01412 {
01413 printf("No hardware acceleration for cscs available\n");
01414 return -CON_ENOTIMPL;
01415 }
01416
01417 if ((vc->mode & CON_OUT)==0)
01418 return -CON_EPERM;
01419
01420 switch (yuv_type)
01421 {
01422 case pSLIM_CSCS_PLN_I420:
01423 if (!hw_accel.caps & ACCEL_FAST_CSCS_YV12)
01424 return -CON_ENOTIMPL;
01425 config.fourcc = IMGFMT_I420;
01426 break;
01427 case pSLIM_CSCS_PLN_YV12:
01428 if (!hw_accel.caps & ACCEL_FAST_CSCS_YV12)
01429 return -CON_ENOTIMPL;
01430 config.fourcc = IMGFMT_YV12;
01431 break;
01432 case pSLIM_CSCS_PCK_YUY2:
01433 if (!hw_accel.caps & ACCEL_FAST_CSCS_YUY2)
01434 return -CON_ENOTIMPL;
01435 config.fourcc = IMGFMT_YUY2;
01436 break;
01437 default:
01438 return -CON_ENOTIMPL;
01439 }
01440
01441 config.src = (vidix_rect_t){ rect_src->x, rect_src->y,
01442 rect_src->w, rect_src->h, { 0, 0, 0 } };
01443 config.dest = (vidix_rect_t){ rect_dst->x, rect_dst->y,
01444 rect_dst->w, rect_dst->h, { 0, 0, 0 } };
01445
01446 if (config.dest.x > vc->client_xres-32)
01447 config.dest.x = vc->client_xres-32;
01448 if (config.dest.y > vc->client_yres-32)
01449 config.dest.y = vc->client_yres-32;
01450 if (config.dest.w < 32)
01451 config.dest.w = 32;
01452 else if (config.dest.w+config.dest.x > vc->client_xres)
01453 config.dest.w = vc->client_xres-config.dest.x;
01454 if (config.dest.h < 32)
01455 config.dest.h = 32;
01456 else if (config.dest.h+config.dest.y > vc->client_yres)
01457 config.dest.h = vc->client_yres-config.dest.y;
01458
01459 if (hw_accel.caps & ACCEL_COLOR_KEY)
01460 {
01461
01462 static vidix_grkey_t gr_key;
01463
01464 gr_key.key_op = KEYS_PUT;
01465 gr_key.ckey.op = CKEY_TRUE;
01466 gr_key.ckey.red = 0xFF;
01467 gr_key.ckey.green = 0x00;
01468 gr_key.ckey.blue = 0xFF;
01469 hw_accel.cscs_grkey(&gr_key);
01470 }
01471
01472 config.num_frames = 1;
01473 hw_accel.cscs_init(&config);
01474
01475 *offs_y = config.offsets[0] + config.offset.y;
01476 *offs_u = config.offsets[0] + config.offset.u;
01477 *offs_v = config.offsets[0] + config.offset.v;
01478
01479
01480 switch (yuv_type)
01481 {
01482 case pSLIM_CSCS_PLN_I420:
01483 case pSLIM_CSCS_PLN_YV12:
01484 {
01485 unsigned size = ((rect_src->w+31)&~31)*rect_src->h;
01486 memset((void*)config.dga_addr+*offs_y, 0, size);
01487 memset((void*)config.dga_addr+*offs_u, 128, size/4);
01488 memset((void*)config.dga_addr+*offs_v, 128, size/4);
01489 }
01490 break;
01491 case pSLIM_CSCS_PCK_YUY2:
01492 {
01493 unsigned stride = 2*((rect_src->w+15)&~15);
01494 unsigned h_size = rect_src->h, w_size = rect_src->w>>1;
01495 unsigned char *dest = (unsigned char*)config.dga_addr+*offs_y;
01496 int i;
01497 for (i=0; i<h_size; i++)
01498 {
01499 int j;
01500 for (j=0; j<w_size; j++)
01501 ((unsigned int*)dest)[j] = 0x80008000;
01502 dest += stride;
01503 }
01504 }
01505 break;
01506 }
01507
01508 hw_accel.cscs_start();
01509
01510 if (hw_accel.caps & ACCEL_EQUALIZER)
01511 {
01512
01513 cscs_eq.cap = VEQ_CAP_BRIGHTNESS | VEQ_CAP_CONTRAST;
01514 cscs_eq.brightness = 300;
01515 cscs_eq.contrast = 300;
01516 hw_accel.cscs_eq(&cscs_eq);
01517 }
01518
01519 if (hw_accel.caps & ACCEL_COLOR_KEY)
01520 {
01521
01522 l4con_pslim_rect_t rect = { config.dest.x, config.dest.y,
01523 config.dest.w, config.dest.h };
01524 l4con_pslim_color_t pink = { 0x00FF00FF };
01525
01526 l4lock_lock(&vc->fb_lock);
01527
01528 convert_color(vc, &pink);
01529 pslim_fill(vc, 0, &rect, pink);
01530
01531 vc->logo_x = config.dest.x + 20;
01532 vc->logo_y = config.dest.y + 20;
01533
01534 l4lock_unlock(&vc->fb_lock);
01535 }
01536
01537 printf("Opening cscs stream %dx%d => %dx%d\n",
01538 config.src.w, config.src.h, config.dest.w, config.dest.h);
01539 buffer->fpage = l4_fpage((l4_addr_t)config.dga_addr,
01540 l4util_log2(config.frame_size),
01541 L4_FPAGE_RW, L4_FPAGE_MAP);
01542
01543 return 0;
01544 }
01545
01546
01547 void
01548 vc_brightness_contrast(int diff_brightness, int diff_contrast)
01549 {
01550 if (hw_accel.caps & ACCEL_EQUALIZER)
01551 {
01552 cscs_eq.cap = VEQ_CAP_BRIGHTNESS | VEQ_CAP_CONTRAST;
01553 cscs_eq.brightness += diff_brightness;
01554 if (cscs_eq.brightness > 1000)
01555 cscs_eq.brightness = 1000;
01556 if (cscs_eq.brightness < -1000)
01557 cscs_eq.brightness = -1000;
01558 cscs_eq.contrast += diff_contrast;
01559 if (cscs_eq.contrast > 1000)
01560 cscs_eq.contrast = 1000;
01561 if (cscs_eq.contrast < -1000)
01562 cscs_eq.contrast = -1000;
01563 hw_accel.cscs_eq(&cscs_eq);
01564 }
01565 }
01566
01567
01568
01569 void
01570 vc_init_rcvstring(int nb, l4_umword_t* addr, l4_umword_t* size,
01571 CORBA_Server_Environment *env)
01572 {
01573 struct l4con_vc *vc = (struct l4con_vc *)(env->user_data);
01574
01575 if (nb==0)
01576 {
01577 *addr = (l4_umword_t)vc->sbuf1;
01578 *size = vc->sbuf1_size;
01579 }
01580 else if (nb == 1)
01581 {
01582 *addr = (l4_umword_t)vc->sbuf2;
01583 *size = vc->sbuf2_size;
01584 }
01585 else if (nb == 2)
01586 {
01587 *addr = (l4_umword_t)vc->sbuf3;
01588 *size = vc->sbuf3_size;
01589 }
01590 else
01591 Panic("unknown string init (%d)", nb);
01592 }
01593
01594 #ifdef ARCH_x86
01595
01596 void vc_pf_entry(void);
01597 asm ("vc_pf_entry: \n\t"
01598 "subl $4, %esp \n\t"
01599 "pusha \n\t"
01600 "push 32(%esp) \n\t"
01601 "call vc_pf_handler \n\t"
01602 "addl $4, %esp \n\t"
01603 "popa \n\t"
01604 "addl $8, %esp \n\t"
01605 "iret \n\t");
01606
01607
01608
01609
01610
01611 static L4_STICKY(void)
01612 vc_pf_handler(l4_addr_t pf_addr)
01613 {
01614 int i;
01615 l4_threadid_t me = l4thread_l4_id(l4thread_myself());
01616
01617 for (i=1; i<=MAX_NR_L4CONS; i++)
01618 {
01619 if (l4_thread_equal(me, vc[i]->vc_l4id))
01620 {
01621 printf("vc[%d]: page fault at "l4_addr_fmt" -- closing\n", i, pf_addr);
01622
01623 vc_close(vc[i]);
01624 if (vc[i]->mode == CON_CLOSING)
01625 {
01626
01627 vc[i]->mode = CON_CLOSED;
01628 l4thread_exit();
01629 }
01630 }
01631 }
01632
01633 printf("page fault in unknown vc (addr="l4_addr_fmt"\n", pf_addr);
01634 enter_kdebug("stop");
01635 }
01636
01637
01638
01639
01640 static void
01641 vc_setup_pf_handler(struct l4con_vc *this_vc)
01642 {
01643 static struct
01644 {
01645 l4util_idt_header_t header;
01646 l4util_idt_desc_t desc[15];
01647 } __attribute__((packed)) idt;
01648
01649 l4util_idt_init(&idt.header, 15);
01650 l4util_idt_entry(&idt.header, 14, (void*)&vc_pf_entry);
01651 l4util_idt_load(&idt.header);
01652
01653 l4rm_enable_pagefault_exceptions();
01654 }
01655
01656 #endif
01657
01658
01659
01660 void
01661 vc_loop(struct l4con_vc *this_vc)
01662 {
01663 CORBA_Server_Environment env = dice_default_server_environment;
01664 env.timeout = L4_IPC_SEND_TIMEOUT_0;
01665 env.user_data = (void*)this_vc;
01666
01667 #ifdef ARCH_x86
01668 vc_setup_pf_handler(this_vc);
01669 #endif
01670
01671 l4thread_started(NULL);
01672
01673 LOG("vc[%d] running as "l4util_idfmt"",
01674 this_vc->vc_number, l4util_idstr(l4thread_l4_id(l4thread_myself())));
01675
01676 con_vc_server_loop(&env);
01677
01678 Panic("IDL IPC error occured");
01679 }
01680
01681 void
01682 vc_error(l4_msgdope_t result, CORBA_Server_Environment *env)
01683 {
01684 #if 0
01685 if (L4_IPC_ERROR(result) == L4_IPC_ENOT_EXISTENT)
01686 {
01687
01688 LOG("Partner thread killed, closing console %d", this_vc->number);
01689 want_vc = this_vc->vc_number |= 0x1000;
01690 }
01691 else
01692 #endif
01693 LOG("vc error %08lx (%s)",
01694 L4_IPC_ERROR(result), l4env_strerror(L4_IPC_ERROR(result)));
01695 }