2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * @OSF_FREE_COPYRIGHT@
33 * @APPLE_FREE_COPYRIGHT@
36 * NetBSD: ite.c,v 1.16 1995/07/17 01:24:34 briggs Exp
38 * Copyright (c) 1988 University of Utah.
39 * Copyright (c) 1990, 1993
40 * The Regents of the University of California. All rights reserved.
42 * This code is derived from software contributed to Berkeley by
43 * the Systems Programming Group of the University of Utah Computer
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 * notice, this list of conditions and the following disclaimer in the
53 * documentation and/or other materials provided with the distribution.
54 * 3. All advertising materials mentioning features or use of this software
55 * must display the following acknowledgement:
56 * This product includes software developed by the University of
57 * California, Berkeley and its contributors.
58 * 4. Neither the name of the University nor the names of its contributors
59 * may be used to endorse or promote products derived from this software
60 * without specific prior written permission.
62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * from: Utah $Hdr: ite.c 1.28 92/12/20$
76 * @(#)ite.c 8.2 (Berkeley) 1/12/94
82 * The ite module handles the system console; that is, stuff printed
83 * by the kernel and by user programs while "desktop" and X aren't
84 * running. Some (very small) parts are based on hp300's 4.4 ite.c,
85 * hence the above copyright.
87 * -- Brad and Lawrence, June 26th, 1994
93 #include <console/video_console.h>
94 #include <console/serial_protos.h>
96 #include <kern/kern_types.h>
97 #include <kern/kalloc.h>
98 #include <kern/debug.h>
99 #include <kern/lock.h>
100 #include <kern/spl.h>
101 #include <kern/thread_call.h>
104 #include <vm/vm_kern.h>
105 #include <machine/io_map_entries.h>
106 #include <machine/machine_cpu.h>
108 #include <pexpert/pexpert.h>
110 #include "iso_font.c"
112 #include "sys/msgbuf.h"
115 * Generic Console (Front-End)
116 * ---------------------------
119 struct vc_info vinfo
;
120 /* if panicDialogDesired is true then we use the panic dialog when its */
121 /* allowed otherwise we won't use the panic dialog even if it is allowed */
122 boolean_t panicDialogDesired
;
125 extern int disableConsoleOutput
;
126 static boolean_t gc_enabled
= FALSE
;
127 static boolean_t gc_initialized
= FALSE
;
128 static boolean_t vm_initialized
= FALSE
;
131 void (*initialize
)(struct vc_info
* info
);
132 void (*enable
)(boolean_t enable
);
133 void (*paint_char
)(unsigned int xx
, unsigned int yy
, unsigned char ch
,
134 int attrs
, unsigned char ch_previous
,
136 void (*clear_screen
)(unsigned int xx
, unsigned int yy
, unsigned int top
,
137 unsigned int bottom
, int which
);
138 void (*scroll_down
)(int num
, unsigned int top
, unsigned int bottom
);
139 void (*scroll_up
)(int num
, unsigned int top
, unsigned int bottom
);
140 void (*hide_cursor
)(unsigned int xx
, unsigned int yy
);
141 void (*show_cursor
)(unsigned int xx
, unsigned int yy
);
142 void (*update_color
)(int color
, boolean_t fore
);
145 static unsigned char *gc_buffer_attributes
;
146 static unsigned char *gc_buffer_characters
;
147 static unsigned char *gc_buffer_colorcodes
;
148 static unsigned long gc_buffer_columns
;
149 static unsigned long gc_buffer_rows
;
150 static unsigned long gc_buffer_size
;
153 decl_simple_lock_data(static, vcputc_lock
);
155 #define VCPUTC_LOCK_INIT() \
157 simple_lock_init(&vcputc_lock, 0); \
160 #define VCPUTC_LOCK_LOCK() \
162 boolean_t istate = ml_get_interrupts_enabled(); \
163 while (!simple_lock_try(&vcputc_lock)) \
166 handle_pending_TLB_flushes(); \
171 #define VCPUTC_LOCK_UNLOCK() \
173 simple_unlock(&vcputc_lock); \
176 static hw_lock_data_t vcputc_lock
;
178 #define VCPUTC_LOCK_INIT() \
180 hw_lock_init(&vcputc_lock); \
183 #define VCPUTC_LOCK_LOCK() \
185 if (!hw_lock_to(&vcputc_lock, LockTimeOut*10)) \
187 panic("VCPUTC_LOCK_LOCK"); \
191 #define VCPUTC_LOCK_UNLOCK() \
193 hw_lock_unlock(&vcputc_lock); \
199 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
201 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
202 # Background color codes:
203 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
209 #define ATTR_REVERSE 4
211 #define COLOR_BACKGROUND 0
212 #define COLOR_FOREGROUND 7
214 #define COLOR_CODE_GET(code, fore) (((code) & ((fore) ? 0xF0 : 0x0F)) >> ((fore) ? 4 : 0))
215 #define COLOR_CODE_SET(code, color, fore) (((code) & ((fore) ? 0x0F : 0xF0)) | ((color) << ((fore) ? 4 : 0)))
217 static unsigned char gc_color_code
;
221 static unsigned int gc_x
, gc_y
, gc_savex
, gc_savey
;
222 static unsigned int gc_par
[MAXPARS
], gc_numpars
, gc_hanging_cursor
, gc_attr
, gc_saveattr
;
224 /* VT100 tab stops & scroll region */
225 static char gc_tab_stops
[255];
226 static unsigned int gc_scrreg_top
, gc_scrreg_bottom
;
228 #ifdef CONFIG_VC_PROGRESS_WHITE
229 enum { kProgressAcquireDelay
= 0 /* secs */ };
231 enum { kProgressAcquireDelay
= 5 /* secs */ };
235 ESnormal
, /* Nothing yet */
237 ESsquare
, /* Got ESC [ */
238 ESgetpars
, /* About to get or getting the parameters */
239 ESgotpars
, /* Finished getting the parameters */
240 ESfunckey
, /* Function key */
241 EShash
, /* DEC-specific stuff (screen align, etc.) */
242 ESsetG0
, /* Specify the G0 character set */
243 ESsetG1
, /* Specify the G1 character set */
246 ESignore
/* Ignore this sequence */
247 } gc_vt100state
= ESnormal
;
249 static int gc_wrap_mode
= 1, gc_relative_origin
= 0;
250 static int gc_charset_select
= 0, gc_save_charset_s
= 0;
251 static int gc_charset
[2] = { 0, 0 };
252 static int gc_charset_save
[2] = { 0, 0 };
254 static void gc_clear_line(unsigned int xx
, unsigned int yy
, int which
);
255 static void gc_clear_screen(unsigned int xx
, unsigned int yy
, int top
,
256 unsigned int bottom
, int which
);
257 static void gc_enable(boolean_t enable
);
258 static void gc_hide_cursor(unsigned int xx
, unsigned int yy
);
259 static void gc_initialize(struct vc_info
* info
);
260 static void gc_paint_char(unsigned int xx
, unsigned int yy
, unsigned char ch
,
262 static void gc_putchar(char ch
);
263 static void gc_putc_askcmd(unsigned char ch
);
264 static void gc_putc_charsetcmd(int charset
, unsigned char ch
);
265 static void gc_putc_charsizecmd(unsigned char ch
);
266 static void gc_putc_esc(unsigned char ch
);
267 static void gc_putc_getpars(unsigned char ch
);
268 static void gc_putc_gotpars(unsigned char ch
);
269 static void gc_putc_normal(unsigned char ch
);
270 static void gc_putc_square(unsigned char ch
);
271 static void gc_reset_screen(void);
272 static void gc_reset_tabs(void);
273 static void gc_reset_vt100(void);
274 static void gc_scroll_down(int num
, unsigned int top
, unsigned int bottom
);
275 static void gc_scroll_up(int num
, unsigned int top
, unsigned int bottom
);
276 static void gc_show_cursor(unsigned int xx
, unsigned int yy
);
277 static void gc_update_color(int color
, boolean_t fore
);
280 gc_clear_line(unsigned int xx
, unsigned int yy
, int which
)
282 unsigned int start
, end
, i
;
285 * This routine runs extremely slowly. I don't think it's
286 * used all that often, except for To end of line. I'll go
287 * back and speed this up when I speed up the whole vc
292 case 0: /* To end of line */
294 end
= vinfo
.v_columns
-1;
296 case 1: /* To start of line */
300 case 2: /* Whole line */
302 end
= vinfo
.v_columns
-1;
308 for (i
= start
; i
<= end
; i
++) {
309 gc_paint_char(i
, yy
, ' ', ATTR_NONE
);
314 gc_clear_screen(unsigned int xx
, unsigned int yy
, int top
, unsigned int bottom
,
317 if (!gc_buffer_size
) return;
319 if ( xx
< gc_buffer_columns
&& yy
< gc_buffer_rows
&& bottom
<= gc_buffer_rows
)
321 unsigned long start
, end
;
324 case 0: /* To end of screen */
325 start
= (yy
* gc_buffer_columns
) + xx
;
326 end
= (bottom
* gc_buffer_columns
) - 1;
328 case 1: /* To start of screen */
329 start
= (top
* gc_buffer_columns
);
330 end
= (yy
* gc_buffer_columns
) + xx
;
332 case 2: /* Whole screen */
333 start
= (top
* gc_buffer_columns
);
334 end
= (bottom
* gc_buffer_columns
) - 1;
342 memset(gc_buffer_attributes
+ start
, ATTR_NONE
, end
- start
+ 1);
343 memset(gc_buffer_characters
+ start
, ' ', end
- start
+ 1);
344 memset(gc_buffer_colorcodes
+ start
, gc_color_code
, end
- start
+ 1);
347 gc_ops
.clear_screen(xx
, yy
, top
, bottom
, which
);
351 gc_enable( boolean_t enable
)
353 unsigned char *buffer_attributes
= NULL
;
354 unsigned char *buffer_characters
= NULL
;
355 unsigned char *buffer_colorcodes
= NULL
;
356 unsigned long buffer_columns
= 0;
357 unsigned long buffer_rows
= 0;
358 unsigned long buffer_size
= 0;
361 if ( enable
== FALSE
)
363 // only disable console output if it goes to the graphics console
364 if ( console_is_serial() == FALSE
)
365 disableConsoleOutput
= TRUE
;
367 gc_ops
.enable(FALSE
);
373 if ( gc_buffer_size
)
375 buffer_attributes
= gc_buffer_attributes
;
376 buffer_characters
= gc_buffer_characters
;
377 buffer_colorcodes
= gc_buffer_colorcodes
;
378 buffer_size
= gc_buffer_size
;
380 gc_buffer_attributes
= NULL
;
381 gc_buffer_characters
= NULL
;
382 gc_buffer_colorcodes
= NULL
;
383 gc_buffer_columns
= 0;
387 VCPUTC_LOCK_UNLOCK( );
390 kfree( buffer_attributes
, buffer_size
);
391 kfree( buffer_characters
, buffer_size
);
392 kfree( buffer_colorcodes
, buffer_size
);
396 VCPUTC_LOCK_UNLOCK( );
402 if ( vm_initialized
)
404 buffer_columns
= vinfo
.v_columns
;
405 buffer_rows
= vinfo
.v_rows
;
406 buffer_size
= buffer_columns
* buffer_rows
;
410 buffer_attributes
= (unsigned char *) kalloc( buffer_size
);
411 buffer_characters
= (unsigned char *) kalloc( buffer_size
);
412 buffer_colorcodes
= (unsigned char *) kalloc( buffer_size
);
414 if ( buffer_attributes
== NULL
||
415 buffer_characters
== NULL
||
416 buffer_colorcodes
== NULL
)
418 if ( buffer_attributes
) kfree( buffer_attributes
, buffer_size
);
419 if ( buffer_characters
) kfree( buffer_characters
, buffer_size
);
420 if ( buffer_colorcodes
) kfree( buffer_colorcodes
, buffer_size
);
428 memset( buffer_attributes
, ATTR_NONE
, buffer_size
);
429 memset( buffer_characters
, ' ', buffer_size
);
430 memset( buffer_colorcodes
, COLOR_CODE_SET( 0, COLOR_FOREGROUND
, TRUE
), buffer_size
);
438 gc_buffer_attributes
= buffer_attributes
;
439 gc_buffer_characters
= buffer_characters
;
440 gc_buffer_colorcodes
= buffer_colorcodes
;
441 gc_buffer_columns
= buffer_columns
;
442 gc_buffer_rows
= buffer_rows
;
443 gc_buffer_size
= buffer_size
;
447 VCPUTC_LOCK_UNLOCK( );
450 gc_ops
.clear_screen(gc_x
, gc_y
, 0, vinfo
.v_rows
, 2);
451 gc_ops
.show_cursor(gc_x
, gc_y
);
455 disableConsoleOutput
= FALSE
;
460 gc_hide_cursor(unsigned int xx
, unsigned int yy
)
462 if ( xx
< gc_buffer_columns
&& yy
< gc_buffer_rows
)
464 unsigned long index
= (yy
* gc_buffer_columns
) + xx
;
465 unsigned char attribute
= gc_buffer_attributes
[index
];
466 unsigned char character
= gc_buffer_characters
[index
];
467 unsigned char colorcode
= gc_buffer_colorcodes
[index
];
468 unsigned char colorcodesave
= gc_color_code
;
470 gc_update_color(COLOR_CODE_GET(colorcode
, TRUE
), TRUE
);
471 gc_update_color(COLOR_CODE_GET(colorcode
, FALSE
), FALSE
);
473 gc_ops
.paint_char(xx
, yy
, character
, attribute
, 0, 0);
475 gc_update_color(COLOR_CODE_GET(colorcodesave
, TRUE
), TRUE
);
476 gc_update_color(COLOR_CODE_GET(colorcodesave
, FALSE
), FALSE
);
480 gc_ops
.hide_cursor(xx
, yy
);
485 gc_initialize(struct vc_info
* info
)
487 if ( gc_initialized
== FALSE
)
492 gc_initialized
= TRUE
;
495 gc_ops
.initialize(info
);
502 gc_paint_char(unsigned int xx
, unsigned int yy
, unsigned char ch
, int attrs
)
504 if ( xx
< gc_buffer_columns
&& yy
< gc_buffer_rows
)
506 unsigned long index
= (yy
* gc_buffer_columns
) + xx
;
508 gc_buffer_attributes
[index
] = attrs
;
509 gc_buffer_characters
[index
] = ch
;
510 gc_buffer_colorcodes
[index
] = gc_color_code
;
513 gc_ops
.paint_char(xx
, yy
, ch
, attrs
, 0, 0);
520 return; /* ignore null characters */
522 switch (gc_vt100state
) {
523 default:gc_vt100state
= ESnormal
; /* FALLTHROUGH */
543 gc_putc_charsizecmd(ch
);
546 gc_putc_charsetcmd(0, ch
);
549 gc_putc_charsetcmd(1, ch
);
553 if (gc_x
>= vinfo
.v_columns
) {
554 if (0 == vinfo
.v_columns
)
557 gc_x
= vinfo
.v_columns
- 1;
559 if (gc_y
>= vinfo
.v_rows
) {
560 if (0 == vinfo
.v_rows
)
563 gc_y
= vinfo
.v_rows
- 1;
568 gc_putc_askcmd(unsigned char ch
)
570 if (ch
>= '0' && ch
<= '9') {
571 gc_par
[gc_numpars
] = (10*gc_par
[gc_numpars
]) + (ch
-'0');
574 gc_vt100state
= ESnormal
;
578 gc_relative_origin
= ch
== 'h';
580 case 7: /* wrap around mode h=1, l=0*/
581 gc_wrap_mode
= ch
== 'h';
590 gc_putc_charsetcmd(int charset
, unsigned char ch
)
592 gc_vt100state
= ESnormal
;
598 gc_charset
[charset
] = 0;
600 case '0' : /* Graphic characters */
602 gc_charset
[charset
] = 0x21;
609 gc_putc_charsizecmd(unsigned char ch
)
611 gc_vt100state
= ESnormal
;
619 case '8' : /* fill 'E's */
622 for (yy
= 0; yy
< vinfo
.v_rows
; yy
++)
623 for (xx
= 0; xx
< vinfo
.v_columns
; xx
++)
624 gc_paint_char(xx
, yy
, 'E', ATTR_NONE
);
632 gc_putc_esc(unsigned char ch
)
634 gc_vt100state
= ESnormal
;
638 gc_vt100state
= ESsquare
;
640 case 'c': /* Reset terminal */
642 gc_clear_screen(gc_x
, gc_y
, 0, vinfo
.v_rows
, 2);
645 case 'D': /* Line feed */
647 if (gc_y
>= gc_scrreg_bottom
-1) {
648 gc_scroll_up(1, gc_scrreg_top
, gc_scrreg_bottom
);
649 gc_y
= gc_scrreg_bottom
- 1;
653 if (ch
== 'E') gc_x
= 0;
655 case 'H': /* Set tab stop */
656 gc_tab_stops
[gc_x
] = 1;
658 case 'M': /* Cursor up */
659 if (gc_y
<= gc_scrreg_top
) {
660 gc_scroll_down(1, gc_scrreg_top
, gc_scrreg_bottom
);
661 gc_y
= gc_scrreg_top
;
669 case '7': /* Save cursor */
672 gc_saveattr
= gc_attr
;
673 gc_save_charset_s
= gc_charset_select
;
674 gc_charset_save
[0] = gc_charset
[0];
675 gc_charset_save
[1] = gc_charset
[1];
677 case '8': /* Restore cursor */
680 gc_attr
= gc_saveattr
;
681 gc_charset_select
= gc_save_charset_s
;
682 gc_charset
[0] = gc_charset_save
[0];
683 gc_charset
[1] = gc_charset_save
[1];
685 case 'Z': /* return terminal ID */
687 case '#': /* change characters height */
688 gc_vt100state
= EScharsize
;
691 gc_vt100state
= ESsetG0
;
693 case ')': /* character set sequence */
694 gc_vt100state
= ESsetG1
;
699 /* Rest not supported */
706 gc_putc_getpars(unsigned char ch
)
709 gc_vt100state
= ESask
;
713 gc_vt100state
= ESnormal
;
717 if (ch
== ';' && gc_numpars
< MAXPARS
- 1) {
720 if (ch
>= '0' && ch
<= '9') {
721 gc_par
[gc_numpars
] *= 10;
722 gc_par
[gc_numpars
] += ch
- '0';
725 gc_vt100state
= ESgotpars
;
731 gc_putc_gotpars(unsigned char ch
)
736 /* special case for vttest for handling cursor
737 movement in escape sequences */
739 gc_vt100state
= ESgotpars
;
742 gc_vt100state
= ESnormal
;
745 gc_y
-= gc_par
[0] ? gc_par
[0] : 1;
746 if (gc_y
< gc_scrreg_top
)
747 gc_y
= gc_scrreg_top
;
750 gc_y
+= gc_par
[0] ? gc_par
[0] : 1;
751 if (gc_y
>= gc_scrreg_bottom
)
752 gc_y
= gc_scrreg_bottom
- 1;
754 case 'C': /* Right */
755 gc_x
+= gc_par
[0] ? gc_par
[0] : 1;
756 if (gc_x
>= vinfo
.v_columns
)
757 gc_x
= vinfo
.v_columns
-1;
760 if (gc_par
[0] > gc_x
)
767 case 'H': /* Set cursor position */
769 gc_x
= gc_par
[1] ? gc_par
[1] - 1 : 0;
770 gc_y
= gc_par
[0] ? gc_par
[0] - 1 : 0;
771 if (gc_relative_origin
)
772 gc_y
+= gc_scrreg_top
;
773 gc_hanging_cursor
= 0;
775 case 'X': /* clear p1 characters */
777 for (i
= gc_x
; i
< gc_x
+ gc_par
[0]; i
++)
778 gc_paint_char(i
, gc_y
, ' ', ATTR_NONE
);
781 case 'J': /* Clear part of screen */
782 gc_clear_screen(gc_x
, gc_y
, 0, vinfo
.v_rows
, gc_par
[0]);
784 case 'K': /* Clear part of line */
785 gc_clear_line(gc_x
, gc_y
, gc_par
[0]);
787 case 'g': /* tab stops */
790 case 2: /* reset tab stops */
791 /* gc_reset_tabs(); */
793 case 3: /* Clear every tabs */
795 for (i
= 0; i
<= vinfo
.v_columns
; i
++)
800 gc_tab_stops
[gc_x
] = 0;
804 case 'm': /* Set attribute */
805 for (i
= 0; i
< gc_numpars
; i
++) {
809 gc_update_color(COLOR_BACKGROUND
, FALSE
);
810 gc_update_color(COLOR_FOREGROUND
, TRUE
);
813 gc_attr
|= ATTR_BOLD
;
816 gc_attr
|= ATTR_UNDER
;
819 gc_attr
|= ATTR_REVERSE
;
822 gc_attr
&= ~ATTR_BOLD
;
825 gc_attr
&= ~ATTR_UNDER
;
828 gc_attr
&= ~ATTR_REVERSE
;
831 case 25: /* blink/no blink */
834 if (gc_par
[i
] >= 30 && gc_par
[i
] <= 37)
835 gc_update_color(gc_par
[i
] - 30, TRUE
);
836 if (gc_par
[i
] >= 40 && gc_par
[i
] <= 47)
837 gc_update_color(gc_par
[i
] - 40, FALSE
);
842 case 'r': /* Set scroll region */
844 /* ensure top < bottom, and both within limits */
845 if ((gc_numpars
> 0) && (gc_par
[0] < vinfo
.v_rows
)) {
846 gc_scrreg_top
= gc_par
[0] ? gc_par
[0] - 1 : 0;
850 if ((gc_numpars
> 1) && (gc_par
[1] <= vinfo
.v_rows
) && (gc_par
[1] > gc_par
[0])) {
851 gc_scrreg_bottom
= gc_par
[1];
852 if (gc_scrreg_bottom
> vinfo
.v_rows
)
853 gc_scrreg_bottom
= vinfo
.v_rows
;
855 gc_scrreg_bottom
= vinfo
.v_rows
;
857 if (gc_relative_origin
)
858 gc_y
= gc_scrreg_top
;
865 gc_putc_normal(unsigned char ch
)
868 case '\a': /* Beep */
870 case 127: /* Delete */
871 case '\b': /* Backspace */
872 if (gc_hanging_cursor
) {
873 gc_hanging_cursor
= 0;
880 while (gc_x
< vinfo
.v_columns
&& !gc_tab_stops
[++gc_x
]);
881 if (gc_x
>= vinfo
.v_columns
)
882 gc_x
= vinfo
.v_columns
-1;
886 case '\n': /* Line feed */
887 if (gc_y
>= gc_scrreg_bottom
-1 ) {
888 gc_scroll_up(1, gc_scrreg_top
, gc_scrreg_bottom
);
889 gc_y
= gc_scrreg_bottom
- 1;
894 case '\r': /* Carriage return */
896 gc_hanging_cursor
= 0;
898 case 0x0e: /* Select G1 charset (Control-N) */
899 gc_charset_select
= 1;
901 case 0x0f: /* Select G0 charset (Control-O) */
902 gc_charset_select
= 0;
904 case 0x18 : /* CAN : cancel */
905 case 0x1A : /* like cancel */
906 /* well, i do nothing here, may be later */
908 case '\033': /* Escape */
909 gc_vt100state
= ESesc
;
910 gc_hanging_cursor
= 0;
914 if (gc_hanging_cursor
) {
916 if (gc_y
>= gc_scrreg_bottom
-1 ) {
917 gc_scroll_up(1, gc_scrreg_top
, gc_scrreg_bottom
);
918 gc_y
= gc_scrreg_bottom
- 1;
922 gc_hanging_cursor
= 0;
924 gc_paint_char(gc_x
, gc_y
, (ch
>= 0x60 && ch
<= 0x7f) ? ch
+ gc_charset
[gc_charset_select
]
926 if (gc_x
== vinfo
.v_columns
- 1) {
927 gc_hanging_cursor
= gc_wrap_mode
;
938 gc_putc_square(unsigned char ch
)
942 for (i
= 0; i
< MAXPARS
; i
++) {
947 gc_vt100state
= ESgetpars
;
954 gc_reset_screen(void)
965 for (i
= 0; i
<= vinfo
.v_columns
; i
++) {
966 gc_tab_stops
[i
] = ((i
% 8) == 0);
976 gc_scrreg_bottom
= vinfo
.v_rows
;
978 gc_charset
[0] = gc_charset
[1] = 0;
979 gc_charset_select
= 0;
981 gc_relative_origin
= 0;
982 gc_update_color(COLOR_BACKGROUND
, FALSE
);
983 gc_update_color(COLOR_FOREGROUND
, TRUE
);
987 gc_scroll_down(int num
, unsigned int top
, unsigned int bottom
)
989 if (!gc_buffer_size
) return;
991 if ( bottom
<= gc_buffer_rows
)
993 unsigned char colorcodesave
= gc_color_code
;
994 unsigned long column
, row
;
995 unsigned long index
, jump
;
997 jump
= num
* gc_buffer_columns
;
999 for ( row
= bottom
- 1 ; row
>= top
+ num
; row
-- )
1001 index
= row
* gc_buffer_columns
;
1003 for ( column
= 0 ; column
< gc_buffer_columns
; index
++, column
++ )
1005 if ( gc_buffer_attributes
[index
] != gc_buffer_attributes
[index
- jump
] ||
1006 gc_buffer_characters
[index
] != gc_buffer_characters
[index
- jump
] ||
1007 gc_buffer_colorcodes
[index
] != gc_buffer_colorcodes
[index
- jump
] )
1009 if ( gc_color_code
!= gc_buffer_colorcodes
[index
- jump
] )
1011 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes
[index
- jump
], TRUE
), TRUE
);
1012 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes
[index
- jump
], FALSE
), FALSE
);
1015 if ( gc_buffer_colorcodes
[index
] != gc_buffer_colorcodes
[index
- jump
] )
1017 gc_ops
.paint_char( /* xx */ column
,
1019 /* ch */ gc_buffer_characters
[index
- jump
],
1020 /* attrs */ gc_buffer_attributes
[index
- jump
],
1021 /* ch_previous */ 0,
1022 /* attrs_previous */ 0 );
1026 gc_ops
.paint_char( /* xx */ column
,
1028 /* ch */ gc_buffer_characters
[index
- jump
],
1029 /* attrs */ gc_buffer_attributes
[index
- jump
],
1030 /* ch_previous */ gc_buffer_characters
[index
],
1031 /* attrs_previous */ gc_buffer_attributes
[index
] );
1034 gc_buffer_attributes
[index
] = gc_buffer_attributes
[index
- jump
];
1035 gc_buffer_characters
[index
] = gc_buffer_characters
[index
- jump
];
1036 gc_buffer_colorcodes
[index
] = gc_buffer_colorcodes
[index
- jump
];
1041 if ( colorcodesave
!= gc_color_code
)
1043 gc_update_color(COLOR_CODE_GET(colorcodesave
, TRUE
), TRUE
);
1044 gc_update_color(COLOR_CODE_GET(colorcodesave
, FALSE
), FALSE
);
1047 /* Now set the freed up lines to the background colour */
1049 for ( row
= top
; row
< top
+ num
; row
++ )
1051 index
= row
* gc_buffer_columns
;
1053 for ( column
= 0 ; column
< gc_buffer_columns
; index
++, column
++ )
1055 if ( gc_buffer_attributes
[index
] != ATTR_NONE
||
1056 gc_buffer_characters
[index
] != ' ' ||
1057 gc_buffer_colorcodes
[index
] != gc_color_code
)
1059 if ( gc_buffer_colorcodes
[index
] != gc_color_code
)
1061 gc_ops
.paint_char( /* xx */ column
,
1064 /* attrs */ ATTR_NONE
,
1065 /* ch_previous */ 0,
1066 /* attrs_previous */ 0 );
1070 gc_ops
.paint_char( /* xx */ column
,
1073 /* attrs */ ATTR_NONE
,
1074 /* ch_previous */ gc_buffer_characters
[index
],
1075 /* attrs_previous */ gc_buffer_attributes
[index
] );
1078 gc_buffer_attributes
[index
] = ATTR_NONE
;
1079 gc_buffer_characters
[index
] = ' ';
1080 gc_buffer_colorcodes
[index
] = gc_color_code
;
1087 gc_ops
.scroll_down(num
, top
, bottom
);
1089 /* Now set the freed up lines to the background colour */
1091 gc_clear_screen(vinfo
.v_columns
- 1, top
+ num
- 1, top
, bottom
, 1);
1096 gc_scroll_up(int num
, unsigned int top
, unsigned int bottom
)
1098 if (!gc_buffer_size
) return;
1100 if ( bottom
<= gc_buffer_rows
)
1102 unsigned char colorcodesave
= gc_color_code
;
1103 unsigned long column
, row
;
1104 unsigned long index
, jump
;
1106 jump
= num
* gc_buffer_columns
;
1108 for ( row
= top
; row
< bottom
- num
; row
++ )
1110 index
= row
* gc_buffer_columns
;
1112 for ( column
= 0 ; column
< gc_buffer_columns
; index
++, column
++ )
1114 if ( gc_buffer_attributes
[index
] != gc_buffer_attributes
[index
+ jump
] ||
1115 gc_buffer_characters
[index
] != gc_buffer_characters
[index
+ jump
] ||
1116 gc_buffer_colorcodes
[index
] != gc_buffer_colorcodes
[index
+ jump
] )
1118 if ( gc_color_code
!= gc_buffer_colorcodes
[index
+ jump
] )
1120 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes
[index
+ jump
], TRUE
), TRUE
);
1121 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes
[index
+ jump
], FALSE
), FALSE
);
1124 if ( gc_buffer_colorcodes
[index
] != gc_buffer_colorcodes
[index
+ jump
] )
1126 gc_ops
.paint_char( /* xx */ column
,
1128 /* ch */ gc_buffer_characters
[index
+ jump
],
1129 /* attrs */ gc_buffer_attributes
[index
+ jump
],
1130 /* ch_previous */ 0,
1131 /* attrs_previous */ 0 );
1135 gc_ops
.paint_char( /* xx */ column
,
1137 /* ch */ gc_buffer_characters
[index
+ jump
],
1138 /* attrs */ gc_buffer_attributes
[index
+ jump
],
1139 /* ch_previous */ gc_buffer_characters
[index
],
1140 /* attrs_previous */ gc_buffer_attributes
[index
] );
1143 gc_buffer_attributes
[index
] = gc_buffer_attributes
[index
+ jump
];
1144 gc_buffer_characters
[index
] = gc_buffer_characters
[index
+ jump
];
1145 gc_buffer_colorcodes
[index
] = gc_buffer_colorcodes
[index
+ jump
];
1150 if ( colorcodesave
!= gc_color_code
)
1152 gc_update_color(COLOR_CODE_GET(colorcodesave
, TRUE
), TRUE
);
1153 gc_update_color(COLOR_CODE_GET(colorcodesave
, FALSE
), FALSE
);
1156 /* Now set the freed up lines to the background colour */
1158 for ( row
= bottom
- num
; row
< bottom
; row
++ )
1160 index
= row
* gc_buffer_columns
;
1162 for ( column
= 0 ; column
< gc_buffer_columns
; index
++, column
++ )
1164 if ( gc_buffer_attributes
[index
] != ATTR_NONE
||
1165 gc_buffer_characters
[index
] != ' ' ||
1166 gc_buffer_colorcodes
[index
] != gc_color_code
)
1168 if ( gc_buffer_colorcodes
[index
] != gc_color_code
)
1170 gc_ops
.paint_char( /* xx */ column
,
1173 /* attrs */ ATTR_NONE
,
1174 /* ch_previous */ 0,
1175 /* attrs_previous */ 0 );
1179 gc_ops
.paint_char( /* xx */ column
,
1182 /* attrs */ ATTR_NONE
,
1183 /* ch_previous */ gc_buffer_characters
[index
],
1184 /* attrs_previous */ gc_buffer_attributes
[index
] );
1187 gc_buffer_attributes
[index
] = ATTR_NONE
;
1188 gc_buffer_characters
[index
] = ' ';
1189 gc_buffer_colorcodes
[index
] = gc_color_code
;
1196 gc_ops
.scroll_up(num
, top
, bottom
);
1198 /* Now set the freed up lines to the background colour */
1200 gc_clear_screen(0, bottom
- num
, top
, bottom
, 0);
1205 gc_show_cursor(unsigned int xx
, unsigned int yy
)
1207 if ( xx
< gc_buffer_columns
&& yy
< gc_buffer_rows
)
1209 unsigned long index
= (yy
* gc_buffer_columns
) + xx
;
1210 unsigned char attribute
= gc_buffer_attributes
[index
];
1211 unsigned char character
= gc_buffer_characters
[index
];
1212 unsigned char colorcode
= gc_buffer_colorcodes
[index
];
1213 unsigned char colorcodesave
= gc_color_code
;
1215 gc_update_color(COLOR_CODE_GET(colorcode
, FALSE
), TRUE
);
1216 gc_update_color(COLOR_CODE_GET(colorcode
, TRUE
), FALSE
);
1218 gc_ops
.paint_char(xx
, yy
, character
, attribute
, 0, 0);
1220 gc_update_color(COLOR_CODE_GET(colorcodesave
, TRUE
), TRUE
);
1221 gc_update_color(COLOR_CODE_GET(colorcodesave
, FALSE
), FALSE
);
1225 gc_ops
.show_cursor(xx
, yy
);
1230 gc_update_color(int color
, boolean_t fore
)
1232 gc_color_code
= COLOR_CODE_SET(gc_color_code
, color
, fore
);
1233 gc_ops
.update_color(color
, fore
);
1237 vcputc(__unused
int l
, __unused
int u
, int c
)
1239 if ( gc_enabled
|| debug_mode
)
1246 gc_hide_cursor(gc_x
, gc_y
);
1248 gc_show_cursor(gc_x
, gc_y
);
1250 VCPUTC_LOCK_UNLOCK();
1256 * Video Console (Back-End)
1257 * ------------------------
1261 * For the color support (Michel Pollet)
1263 static unsigned char vc_color_index_table
[33] =
1264 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1265 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
1267 static unsigned long vc_colors
[8][3] = {
1268 { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
1269 { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
1270 { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
1271 { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
1272 { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
1273 // { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
1274 { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
1275 { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
1276 { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
1279 static unsigned long vc_color_fore
= 0;
1280 static unsigned long vc_color_back
= 0;
1283 * New Rendering code from Michel Pollet
1286 /* Rendered Font Buffer */
1287 static unsigned char *vc_rendered_font
= NULL
;
1289 /* Rendered Font Size */
1290 static unsigned long vc_rendered_font_size
= 0;
1292 /* Size of a character in the table (bytes) */
1293 static int vc_rendered_char_size
= 0;
1295 #define REN_MAX_DEPTH 32
1296 static unsigned char vc_rendered_char
[ISO_CHAR_HEIGHT
* ((REN_MAX_DEPTH
/ 8) * ISO_CHAR_WIDTH
)];
1299 vc_clear_screen(unsigned int xx
, unsigned int yy
, unsigned int scrreg_top
,
1300 unsigned int scrreg_bottom
, int which
)
1302 unsigned long *p
, *endp
, *row
;
1304 int rowline
, rowlongs
;
1309 linelongs
= vinfo
.v_rowbytes
* (ISO_CHAR_HEIGHT
>> 2);
1310 rowline
= vinfo
.v_rowscanbytes
>> 2;
1311 rowlongs
= vinfo
.v_rowbytes
>> 2;
1313 p
= (unsigned long*) vinfo
.v_baseaddr
;
1314 endp
= (unsigned long*) vinfo
.v_baseaddr
;
1317 case 0: /* To end of screen */
1318 gc_clear_line(xx
, yy
, 0);
1319 if (yy
< scrreg_bottom
- 1) {
1320 p
+= (yy
+ 1) * linelongs
;
1321 endp
+= scrreg_bottom
* linelongs
;
1324 case 1: /* To start of screen */
1325 gc_clear_line(xx
, yy
, 1);
1326 if (yy
> scrreg_top
) {
1327 p
+= scrreg_top
* linelongs
;
1328 endp
+= yy
* linelongs
;
1331 case 2: /* Whole screen */
1332 p
+= scrreg_top
* linelongs
;
1333 if (scrreg_bottom
== vinfo
.v_rows
) {
1334 endp
+= rowlongs
* vinfo
.v_height
;
1336 endp
+= scrreg_bottom
* linelongs
;
1341 for (row
= p
; row
< endp
; row
+= rowlongs
) {
1342 for (col
= 0; col
< rowline
; col
++)
1343 *(row
+col
) = vc_color_back
;
1348 vc_initialize(__unused
struct vc_info
* vinfo_p
)
1351 vinfo
.v_rows
= vinfo
.v_height
/ ISO_CHAR_HEIGHT
;
1352 vinfo
.v_columns
= vinfo
.v_width
/ ISO_CHAR_WIDTH
;
1353 vinfo
.v_rowscanbytes
= (vinfo
.v_depth
/ 8) * vinfo
.v_width
;
1357 vc_render_char(unsigned char ch
, unsigned char *renderptr
, short newdepth
)
1360 unsigned char *charptr
;
1361 unsigned short *shortptr
;
1362 unsigned long *longptr
;
1363 } current
; /* current place in rendered font, multiple types. */
1364 unsigned char *theChar
; /* current char in iso_font */
1367 current
.charptr
= renderptr
;
1368 theChar
= iso_font
+ (ch
* ISO_CHAR_HEIGHT
);
1370 for (line
= 0; line
< ISO_CHAR_HEIGHT
; line
++) {
1371 unsigned char mask
= 1;
1375 *current
.charptr
++ = (*theChar
& mask
) ? 0xFF : 0;
1378 *current
.shortptr
++ = (*theChar
& mask
) ? 0xFFFF : 0;
1382 *current
.longptr
++ = (*theChar
& mask
) ? 0xFFFFFFFF : 0;
1386 } while (mask
); /* while the single bit drops to the right */
1392 vc_paint_char_8(unsigned int xx
, unsigned int yy
, unsigned char ch
, int attrs
,
1393 __unused
unsigned char ch_previous
, __unused
int attrs_previous
)
1395 unsigned long *theChar
;
1396 unsigned long *where
;
1399 if (vc_rendered_font
) {
1400 theChar
= (unsigned long*)(vc_rendered_font
+ (ch
* vc_rendered_char_size
));
1402 vc_render_char(ch
, vc_rendered_char
, 8);
1403 theChar
= (unsigned long*)(vc_rendered_char
);
1405 where
= (unsigned long*)(vinfo
.v_baseaddr
+
1406 (yy
* ISO_CHAR_HEIGHT
* vinfo
.v_rowbytes
) +
1407 (xx
* ISO_CHAR_WIDTH
));
1409 if (!attrs
) for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* No attr? FLY !*/
1410 unsigned long *store
= where
;
1412 for (x
= 0; x
< 2; x
++) {
1413 unsigned long val
= *theChar
++;
1414 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1418 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1419 } else for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* a little slower */
1420 unsigned long *store
= where
, lastpixel
= 0;
1422 for (x
= 0 ; x
< 2; x
++) {
1423 unsigned long val
= *theChar
++, save
= val
;
1424 if (attrs
& ATTR_BOLD
) { /* bold support */
1425 if (lastpixel
&& !(save
& 0xFF000000))
1427 if ((save
& 0xFFFF0000) == 0xFF000000)
1429 if ((save
& 0x00FFFF00) == 0x00FF0000)
1431 if ((save
& 0x0000FFFF) == 0x0000FF00)
1434 if (attrs
& ATTR_REVERSE
) val
= ~val
;
1435 if (attrs
& ATTR_UNDER
&& i
== ISO_CHAR_HEIGHT
-1) val
= ~val
;
1437 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1439 lastpixel
= save
& 0xff;
1442 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1448 vc_paint_char_16(unsigned int xx
, unsigned int yy
, unsigned char ch
, int attrs
,
1449 __unused
unsigned char ch_previous
,
1450 __unused
int attrs_previous
)
1452 unsigned long *theChar
;
1453 unsigned long *where
;
1456 if (vc_rendered_font
) {
1457 theChar
= (unsigned long*)(vc_rendered_font
+ (ch
* vc_rendered_char_size
));
1459 vc_render_char(ch
, vc_rendered_char
, 16);
1460 theChar
= (unsigned long*)(vc_rendered_char
);
1462 where
= (unsigned long*)(vinfo
.v_baseaddr
+
1463 (yy
* ISO_CHAR_HEIGHT
* vinfo
.v_rowbytes
) +
1464 (xx
* ISO_CHAR_WIDTH
* 2));
1466 if (!attrs
) for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* No attrs ? FLY ! */
1467 unsigned long *store
= where
;
1469 for (x
= 0; x
< 4; x
++) {
1470 unsigned long val
= *theChar
++;
1471 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1475 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1476 } else for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* a little bit slower */
1477 unsigned long *store
= where
, lastpixel
= 0;
1479 for (x
= 0 ; x
< 4; x
++) {
1480 unsigned long val
= *theChar
++, save
= val
;
1481 if (attrs
& ATTR_BOLD
) { /* bold support */
1482 if (save
== 0xFFFF0000) val
|= 0xFFFF;
1483 else if (lastpixel
&& !(save
& 0xFFFF0000))
1486 if (attrs
& ATTR_REVERSE
) val
= ~val
;
1487 if (attrs
& ATTR_UNDER
&& i
== ISO_CHAR_HEIGHT
-1) val
= ~val
;
1489 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1492 lastpixel
= save
& 0x7fff;
1495 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1501 vc_paint_char_32(unsigned int xx
, unsigned int yy
, unsigned char ch
, int attrs
,
1502 unsigned char ch_previous
, int attrs_previous
)
1504 unsigned long *theChar
;
1505 unsigned long *theCharPrevious
;
1506 unsigned long *where
;
1509 if (vc_rendered_font
) {
1510 theChar
= (unsigned long*)(vc_rendered_font
+ (ch
* vc_rendered_char_size
));
1511 theCharPrevious
= (unsigned long*)(vc_rendered_font
+ (ch_previous
* vc_rendered_char_size
));
1513 vc_render_char(ch
, vc_rendered_char
, 32);
1514 theChar
= (unsigned long*)(vc_rendered_char
);
1515 theCharPrevious
= NULL
;
1518 theCharPrevious
= NULL
;
1520 if (attrs_previous
) {
1521 theCharPrevious
= NULL
;
1523 where
= (unsigned long*)(vinfo
.v_baseaddr
+
1524 (yy
* ISO_CHAR_HEIGHT
* vinfo
.v_rowbytes
) +
1525 (xx
* ISO_CHAR_WIDTH
* 4));
1527 if (!attrs
) for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* No attrs ? FLY ! */
1528 unsigned long *store
= where
;
1530 for (x
= 0; x
< 8; x
++) {
1531 unsigned long val
= *theChar
++;
1532 if (theCharPrevious
== NULL
|| val
!= *theCharPrevious
++ ) {
1533 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1540 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1541 } else for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* a little slower */
1542 unsigned long *store
= where
, lastpixel
= 0;
1544 for (x
= 0 ; x
< 8; x
++) {
1545 unsigned long val
= *theChar
++, save
= val
;
1546 if (attrs
& ATTR_BOLD
) { /* bold support */
1547 if (lastpixel
&& !save
)
1550 if (attrs
& ATTR_REVERSE
) val
= ~val
;
1551 if (attrs
& ATTR_UNDER
&& i
== ISO_CHAR_HEIGHT
-1) val
= ~val
;
1553 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1558 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1564 vc_paint_char(unsigned int xx
, unsigned int yy
, unsigned char ch
, int attrs
,
1565 unsigned char ch_previous
, int attrs_previous
)
1570 switch(vinfo
.v_depth
) {
1572 vc_paint_char_8(xx
, yy
, ch
, attrs
, ch_previous
, attrs_previous
);
1575 vc_paint_char_16(xx
, yy
, ch
, attrs
, ch_previous
,
1579 vc_paint_char_32(xx
, yy
, ch
, attrs
, ch_previous
,
1586 vc_render_font(short newdepth
)
1588 static short olddepth
= 0;
1590 int charindex
; /* index in ISO font */
1591 unsigned char *rendered_font
;
1592 unsigned long rendered_font_size
;
1593 int rendered_char_size
;
1596 if (vm_initialized
== FALSE
) {
1597 return; /* nothing to do */
1599 if (olddepth
== newdepth
&& vc_rendered_font
) {
1600 return; /* nothing to do */
1606 rendered_font
= vc_rendered_font
;
1607 rendered_font_size
= vc_rendered_font_size
;
1608 rendered_char_size
= vc_rendered_char_size
;
1610 vc_rendered_font
= NULL
;
1611 vc_rendered_font_size
= 0;
1612 vc_rendered_char_size
= 0;
1614 VCPUTC_LOCK_UNLOCK();
1617 if (rendered_font
) {
1618 kfree(rendered_font
, rendered_font_size
);
1619 rendered_font
= NULL
;
1623 rendered_char_size
= ISO_CHAR_HEIGHT
* ((newdepth
/ 8) * ISO_CHAR_WIDTH
);
1624 rendered_font_size
= (ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * rendered_char_size
;
1625 rendered_font
= (unsigned char *) kalloc(rendered_font_size
);
1628 if (rendered_font
== NULL
) {
1632 for (charindex
= ISO_CHAR_MIN
; charindex
<= ISO_CHAR_MAX
; charindex
++) {
1633 vc_render_char(charindex
, rendered_font
+ (charindex
* rendered_char_size
), newdepth
);
1636 olddepth
= newdepth
;
1641 vc_rendered_font
= rendered_font
;
1642 vc_rendered_font_size
= rendered_font_size
;
1643 vc_rendered_char_size
= rendered_char_size
;
1645 VCPUTC_LOCK_UNLOCK();
1650 vc_enable(boolean_t enable
)
1652 vc_render_font(enable
? vinfo
.v_depth
: 0);
1656 vc_reverse_cursor(unsigned int xx
, unsigned int yy
)
1658 unsigned long *where
;
1664 where
= (unsigned long*)(vinfo
.v_baseaddr
+
1665 (yy
* ISO_CHAR_HEIGHT
* vinfo
.v_rowbytes
) +
1666 (xx
/** ISO_CHAR_WIDTH*/ * vinfo
.v_depth
));
1667 for (line
= 0; line
< ISO_CHAR_HEIGHT
; line
++) {
1668 switch (vinfo
.v_depth
) {
1670 where
[0] = ~where
[0];
1671 where
[1] = ~where
[1];
1674 for (col
= 0; col
< 4; col
++)
1675 where
[col
] = ~where
[col
];
1678 for (col
= 0; col
< 8; col
++)
1679 where
[col
] = ~where
[col
];
1682 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1687 vc_scroll_down(int num
, unsigned int scrreg_top
, unsigned int scrreg_bottom
)
1689 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
1694 linelongs
= vinfo
.v_rowbytes
* (ISO_CHAR_HEIGHT
>> 2);
1695 rowline
= vinfo
.v_rowbytes
>> 2;
1696 rowscanline
= vinfo
.v_rowscanbytes
>> 2;
1698 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_bottom
)
1699 - (rowline
- rowscanline
);
1700 from
= to
- (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
1702 i
= (scrreg_bottom
- scrreg_top
) - num
;
1705 for (line
= 0; line
< ISO_CHAR_HEIGHT
; line
++) {
1707 * Only copy what is displayed
1709 video_scroll_down((unsigned int) from
,
1710 (unsigned int) (from
-(vinfo
.v_rowscanbytes
>> 2)),
1720 vc_scroll_up(int num
, unsigned int scrreg_top
, unsigned int scrreg_bottom
)
1722 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
1727 linelongs
= vinfo
.v_rowbytes
* (ISO_CHAR_HEIGHT
>> 2);
1728 rowline
= vinfo
.v_rowbytes
>> 2;
1729 rowscanline
= vinfo
.v_rowscanbytes
>> 2;
1731 to
= (unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
);
1732 from
= to
+ (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
1734 i
= (scrreg_bottom
- scrreg_top
) - num
;
1737 for (line
= 0; line
< ISO_CHAR_HEIGHT
; line
++) {
1739 * Only copy what is displayed
1741 video_scroll_up((unsigned int) from
,
1742 (unsigned int) (from
+(vinfo
.v_rowscanbytes
>> 2)),
1752 vc_update_color(int color
, boolean_t fore
)
1757 vc_color_fore
= vc_colors
[color
][vc_color_index_table
[vinfo
.v_depth
]];
1759 vc_color_back
= vc_colors
[color
][vc_color_index_table
[vinfo
.v_depth
]];
1764 * Video Console (Back-End): Icon Control
1765 * --------------------------------------
1768 struct vc_progress_element
{
1769 unsigned int version
;
1772 unsigned char count
;
1773 unsigned char res
[3];
1779 unsigned int res2
[3];
1780 unsigned char data
[0];
1782 typedef struct vc_progress_element vc_progress_element
;
1784 static vc_progress_element
* vc_progress
;
1785 static const unsigned char * vc_progress_data
;
1786 static const unsigned char * vc_progress_alpha
;
1787 static boolean_t vc_progress_enable
;
1788 static const unsigned char * vc_clut
;
1789 static const unsigned char * vc_clut8
;
1790 static unsigned char vc_revclut8
[256];
1791 static uint32_t vc_progress_interval
;
1792 static uint64_t vc_progress_deadline
;
1793 static thread_call_data_t vc_progress_call
;
1794 static boolean_t vc_needsave
;
1795 static void * vc_saveunder
;
1796 static vm_size_t vc_saveunder_len
;
1797 decl_simple_lock_data(,vc_progress_lock
)
1799 static void vc_blit_rect( int x
, int y
, int width
, int height
,
1800 const unsigned char * dataPtr
, const unsigned char * alphaPtr
,
1801 void * backBuffer
, boolean_t save
, boolean_t static_alpha
);
1802 static void vc_blit_rect_8( int x
, int y
, int width
, int height
,
1803 const unsigned char * dataPtr
, const unsigned char * alphaPtr
,
1804 unsigned char * backBuffer
, boolean_t save
, boolean_t static_alpha
);
1805 static void vc_blit_rect_16( int x
, int y
, int width
, int height
,
1806 const unsigned char * dataPtr
, const unsigned char * alphaPtr
,
1807 unsigned short * backBuffer
, boolean_t save
, boolean_t static_alpha
);
1808 static void vc_blit_rect_32( int x
, int y
, int width
, int height
,
1809 const unsigned char * dataPtr
, const unsigned char * alphaPtr
,
1810 unsigned int * backBuffer
, boolean_t save
, boolean_t static_alpha
);
1811 extern void vc_display_icon( vc_progress_element
* desc
, const unsigned char * data
);
1812 extern void vc_progress_initialize( vc_progress_element
* desc
, const unsigned char * data
, const unsigned char * clut
);
1813 static void vc_progress_set(boolean_t enable
, uint32_t vc_delay
);
1814 static void vc_progress_task( void * arg0
, void * arg
);
1816 static void vc_blit_rect( int x
, int y
,
1817 int width
, int height
,
1818 const unsigned char * dataPtr
,
1819 const unsigned char * alphaPtr
,
1821 boolean_t save
, boolean_t static_alpha
)
1826 switch( vinfo
.v_depth
) {
1828 if( vc_clut8
== vc_clut
)
1829 vc_blit_rect_8( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned char *) backBuffer
, save
, static_alpha
);
1832 vc_blit_rect_16( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned short *) backBuffer
, save
, static_alpha
);
1835 vc_blit_rect_32( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned int *) backBuffer
, save
, static_alpha
);
1841 vc_blit_rect_8(int x
, int y
, int width
, int height
,
1842 const unsigned char * dataPtr
, const unsigned char * alphaPtr
,
1843 __unused
unsigned char * backPtr
, __unused boolean_t save
,
1844 __unused boolean_t static_alpha
)
1846 volatile unsigned char * dst
;
1850 dst
= (unsigned char *)(vinfo
.v_baseaddr
+
1851 (y
* vinfo
.v_rowbytes
) +
1854 for( line
= 0; line
< height
; line
++) {
1855 for( col
= 0; col
< width
; col
++) {
1857 if( dataPtr
!= 0) data
= *dataPtr
++;
1858 else if( alphaPtr
!= 0) data
= vc_revclut8
[*alphaPtr
++];
1859 *(dst
+ col
) = data
;
1861 dst
= (volatile unsigned char *) (((int)dst
) + vinfo
.v_rowbytes
);
1865 /* For ARM, 16-bit is 565 (RGB); it is 1555 (XRGB) on other platforms */
1867 #define CLUT_MASK_R 0xf8
1868 #define CLUT_MASK_G 0xf8
1869 #define CLUT_MASK_B 0xf8
1870 #define CLUT_SHIFT_R << 7
1871 #define CLUT_SHIFT_G << 2
1872 #define CLUT_SHIFT_B >> 3
1873 #define MASK_R 0x7c00
1874 #define MASK_G 0x03e0
1875 #define MASK_B 0x001f
1876 #define MASK_R_8 0x3fc00
1877 #define MASK_G_8 0x01fe0
1878 #define MASK_B_8 0x000ff
1880 static void vc_blit_rect_16( int x
, int y
,
1881 int width
, int height
,
1882 const unsigned char * dataPtr
,
1883 const unsigned char * alphaPtr
,
1884 unsigned short * backPtr
,
1885 boolean_t save
, boolean_t static_alpha
)
1887 volatile unsigned short * dst
;
1889 unsigned int data
= 0, index
= 0, alpha
, back
;
1891 dst
= (volatile unsigned short *)(vinfo
.v_baseaddr
+
1892 (y
* vinfo
.v_rowbytes
) +
1895 for( line
= 0; line
< height
; line
++) {
1896 for( col
= 0; col
< width
; col
++) {
1902 if( alphaPtr
&& backPtr
) {
1904 alpha
= *alphaPtr
++;
1907 if( vc_clut
[index
+ 0] > alpha
)
1908 data
|= (((vc_clut
[index
+ 0] - alpha
) & CLUT_MASK_R
) CLUT_SHIFT_R
);
1909 if( vc_clut
[index
+ 1] > alpha
)
1910 data
|= (((vc_clut
[index
+ 1] - alpha
) & CLUT_MASK_G
) CLUT_SHIFT_G
);
1911 if( vc_clut
[index
+ 2] > alpha
)
1912 data
|= (((vc_clut
[index
+ 2] - alpha
) & CLUT_MASK_B
) CLUT_SHIFT_B
);
1914 #ifdef CONFIG_VC_PROGRESS_WHITE
1916 data
|= (((0xff - alpha
) & CLUT_MASK_R
) CLUT_SHIFT_R
);
1917 data
|= (((0xff - alpha
) & CLUT_MASK_G
) CLUT_SHIFT_G
);
1918 data
|= (((0xff - alpha
) & CLUT_MASK_B
) CLUT_SHIFT_B
);
1923 back
= *(dst
+ col
);
1926 back
= (((((back
& MASK_R
) * alpha
) + MASK_R_8
) >> 8) & MASK_R
)
1927 | (((((back
& MASK_G
) * alpha
) + MASK_G_8
) >> 8) & MASK_G
)
1928 | (((((back
& MASK_B
) * alpha
) + MASK_B_8
) >> 8) & MASK_B
);
1933 if ( !static_alpha
) {
1934 back
= (((((back
& MASK_R
) * alpha
) + MASK_R_8
) >> 8) & MASK_R
)
1935 | (((((back
& MASK_G
) * alpha
) + MASK_G_8
) >> 8) & MASK_G
)
1936 | (((((back
& MASK_B
) * alpha
) + MASK_B_8
) >> 8) & MASK_B
);
1944 data
= ( (CLUT_MASK_R
& (vc_clut
[index
+ 0])) CLUT_SHIFT_R
)
1945 | ( (CLUT_MASK_G
& (vc_clut
[index
+ 1])) CLUT_SHIFT_G
)
1946 | ( (CLUT_MASK_B
& (vc_clut
[index
+ 2])) CLUT_SHIFT_B
);
1949 *(dst
+ col
) = data
;
1951 dst
= (volatile unsigned short *) (((int)dst
) + vinfo
.v_rowbytes
);
1955 static void vc_blit_rect_32( int x
, int y
,
1956 int width
, int height
,
1957 const unsigned char * dataPtr
,
1958 const unsigned char * alphaPtr
,
1959 unsigned int * backPtr
,
1960 boolean_t save
, boolean_t static_alpha
)
1962 volatile unsigned int * dst
;
1964 unsigned int data
= 0, index
= 0, alpha
, back
;
1966 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
1967 (y
* vinfo
.v_rowbytes
) +
1970 for( line
= 0; line
< height
; line
++) {
1971 for( col
= 0; col
< width
; col
++) {
1977 if( alphaPtr
&& backPtr
) {
1979 alpha
= *alphaPtr
++;
1982 if( vc_clut
[index
+ 0] > alpha
)
1983 data
|= ((vc_clut
[index
+ 0] - alpha
) << 16);
1984 if( vc_clut
[index
+ 1] > alpha
)
1985 data
|= ((vc_clut
[index
+ 1] - alpha
) << 8);
1986 if( vc_clut
[index
+ 2] > alpha
)
1987 data
|= ((vc_clut
[index
+ 2] - alpha
));
1989 #ifdef CONFIG_VC_PROGRESS_WHITE
1991 data
|= (0xff - alpha
) << 16;
1992 data
|= (0xff - alpha
) << 8;
1993 data
|= (0xff - alpha
);
1998 back
= *(dst
+ col
);
2001 back
= (((((back
& 0x00ff00ff) * alpha
) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2002 | (((((back
& 0x0000ff00) * alpha
) + 0x0000ff00) >> 8) & 0x0000ff00);
2007 if ( !static_alpha
) {
2008 back
= (((((back
& 0x00ff00ff) * alpha
) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2009 | (((((back
& 0x0000ff00) * alpha
) + 0x0000ff00) >> 8) & 0x0000ff00);
2017 data
= (vc_clut
[index
+ 0] << 16)
2018 | (vc_clut
[index
+ 1] << 8)
2019 | (vc_clut
[index
+ 2]);
2022 *(dst
+ col
) = data
;
2024 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2028 void vc_display_icon( vc_progress_element
* desc
,
2029 const unsigned char * data
)
2031 int x
, y
, width
, height
;
2033 if( vc_progress_enable
&& vc_clut
) {
2035 width
= desc
->width
;
2036 height
= desc
->height
;
2039 if( 1 & desc
->flags
) {
2040 x
+= ((vinfo
.v_width
- width
) / 2);
2041 y
+= ((vinfo
.v_height
- height
) / 2);
2043 vc_blit_rect( x
, y
, width
, height
, data
, NULL
, NULL
, FALSE
, TRUE
);
2048 vc_progress_initialize( vc_progress_element
* desc
,
2049 const unsigned char * data
,
2050 const unsigned char * clut
)
2054 if( (!clut
) || (!desc
) || (!data
))
2059 simple_lock_init(&vc_progress_lock
, 0);
2062 vc_progress_data
= data
;
2063 if( 2 & vc_progress
->flags
)
2064 vc_progress_alpha
= vc_progress_data
2065 + vc_progress
->count
* vc_progress
->width
* vc_progress
->height
;
2067 vc_progress_alpha
= NULL
;
2069 thread_call_setup(&vc_progress_call
, vc_progress_task
, NULL
);
2071 clock_interval_to_absolutetime_interval(vc_progress
->time
, 1000 * 1000, &abstime
);
2072 vc_progress_interval
= abstime
;
2076 vc_progress_set(boolean_t enable
, uint32_t vc_delay
)
2079 void *saveBuf
= NULL
;
2080 vm_size_t saveLen
= 0;
2083 unsigned char pdata8
;
2084 unsigned short pdata16
;
2085 unsigned short * buf16
;
2086 unsigned int pdata32
;
2087 unsigned int * buf32
;
2093 saveLen
= vc_progress
->width
* vc_progress
->height
* vinfo
.v_depth
/ 8;
2094 saveBuf
= kalloc( saveLen
);
2096 switch( vinfo
.v_depth
) {
2098 for( count
= 0; count
< 256; count
++) {
2099 vc_revclut8
[count
] = vc_clut
[0x01 * 3];
2100 pdata8
= (vc_clut
[0x01 * 3] * count
+ 0x0ff) >> 8;
2101 for( index
= 0; index
< 256; index
++) {
2102 if( (pdata8
== vc_clut
[index
* 3 + 0]) &&
2103 (pdata8
== vc_clut
[index
* 3 + 1]) &&
2104 (pdata8
== vc_clut
[index
* 3 + 2])) {
2105 vc_revclut8
[count
] = index
;
2110 memset( saveBuf
, 0x01, saveLen
);
2114 buf16
= (unsigned short *) saveBuf
;
2115 pdata16
= ((vc_clut
[0x01 * 3 + 0] & CLUT_MASK_R
) CLUT_SHIFT_R
)
2116 | ((vc_clut
[0x01 * 3 + 0] & CLUT_MASK_G
) CLUT_SHIFT_G
)
2117 | ((vc_clut
[0x01 * 3 + 0] & CLUT_MASK_B
) CLUT_SHIFT_B
);
2118 for( count
= 0; count
< saveLen
/ 2; count
++)
2119 buf16
[count
] = pdata16
;
2123 buf32
= (unsigned int *) saveBuf
;
2124 pdata32
= ((vc_clut
[0x01 * 3 + 0] & 0xff) << 16)
2125 | ((vc_clut
[0x01 * 3 + 1] & 0xff) << 8)
2126 | ((vc_clut
[0x01 * 3 + 2] & 0xff) << 0);
2127 for( count
= 0; count
< saveLen
/ 4; count
++)
2128 buf32
[count
] = pdata32
;
2134 simple_lock(&vc_progress_lock
);
2136 if( vc_progress_enable
!= enable
) {
2137 vc_progress_enable
= enable
;
2140 vc_saveunder
= saveBuf
;
2141 vc_saveunder_len
= saveLen
;
2145 clock_interval_to_deadline(vc_delay
,
2146 1000 * 1000 * 1000 /*second scale*/,
2147 &vc_progress_deadline
);
2148 thread_call_enter_delayed(&vc_progress_call
, vc_progress_deadline
);
2152 saveBuf
= vc_saveunder
;
2153 saveLen
= vc_saveunder_len
;
2154 vc_saveunder
= NULL
;
2155 vc_saveunder_len
= 0;
2158 thread_call_cancel(&vc_progress_call
);
2162 simple_unlock(&vc_progress_lock
);
2166 kfree( saveBuf
, saveLen
);
2170 vc_progress_task(__unused
void *arg0
, void *arg
)
2173 int count
= (int) arg
;
2174 int x
, y
, width
, height
;
2175 const unsigned char * data
;
2178 simple_lock(&vc_progress_lock
);
2180 if( vc_progress_enable
) {
2183 if( count
>= vc_progress
->count
)
2186 width
= vc_progress
->width
;
2187 height
= vc_progress
->height
;
2188 x
= vc_progress
->dx
;
2189 y
= vc_progress
->dy
;
2190 data
= vc_progress_data
;
2191 data
+= count
* width
* height
;
2192 if( 1 & vc_progress
->flags
) {
2193 x
+= ((vinfo
.v_width
- width
) / 2);
2194 y
+= ((vinfo
.v_height
- height
) / 2);
2196 vc_blit_rect( x
, y
, width
, height
,
2197 NULL
, data
, vc_saveunder
,
2198 vc_needsave
, (0 == (4 & vc_progress
->flags
)) );
2199 vc_needsave
= FALSE
;
2201 clock_deadline_for_periodic_event(vc_progress_interval
, mach_absolute_time(), &vc_progress_deadline
);
2202 thread_call_enter1_delayed(&vc_progress_call
, (void *)count
, vc_progress_deadline
);
2204 simple_unlock(&vc_progress_lock
);
2209 * Generic Console (Front-End): Master Control
2210 * -------------------------------------------
2214 #include <console/i386/text_console.h>
2215 #include <pexpert/i386/boot.h>
2216 #endif /* __i386__ */
2218 static boolean_t gc_acquired
= FALSE
;
2219 static boolean_t gc_graphics_boot
= FALSE
;
2220 static boolean_t gc_desire_text
= FALSE
;
2222 static unsigned int lastVideoPhys
= 0;
2223 static unsigned int lastVideoVirt
= 0;
2224 static unsigned int lastVideoSize
= 0;
2225 static boolean_t lastVideoMapped
= FALSE
;
2228 initialize_screen(PE_Video
* boot_vinfo
, unsigned int op
)
2230 unsigned int fbsize
= 0;
2231 unsigned int newVideoVirt
= 0;
2232 boolean_t graphics_now
;
2237 struct vc_info new_vinfo
= vinfo
;
2239 // bcopy((const void *)boot_vinfo, (void *)&boot_video_info, sizeof(boot_video_info));
2242 * First, check if we are changing the size and/or location of the framebuffer
2244 new_vinfo
.v_name
[0] = 0;
2245 new_vinfo
.v_width
= boot_vinfo
->v_width
;
2246 new_vinfo
.v_height
= boot_vinfo
->v_height
;
2247 new_vinfo
.v_depth
= boot_vinfo
->v_depth
;
2248 new_vinfo
.v_rowbytes
= boot_vinfo
->v_rowBytes
;
2249 new_vinfo
.v_physaddr
= boot_vinfo
->v_baseAddr
; /* Get the physical address */
2251 new_vinfo
.v_type
= boot_vinfo
->v_display
;
2253 new_vinfo
.v_type
= 0;
2256 if (!lastVideoMapped
)
2257 kprintf("initialize_screen: b=%08lX, w=%08lX, h=%08lX, r=%08lX, d=%08lX\n", /* (BRINGUP) */
2258 new_vinfo
.v_physaddr
, new_vinfo
.v_width
, new_vinfo
.v_height
, new_vinfo
.v_rowbytes
, new_vinfo
.v_type
); /* (BRINGUP) */
2261 if ( (new_vinfo
.v_type
== VGA_TEXT_MODE
) )
2263 if (new_vinfo
.v_physaddr
== 0) {
2264 new_vinfo
.v_physaddr
= 0xb8000;
2265 new_vinfo
.v_width
= 80;
2266 new_vinfo
.v_height
= 25;
2267 new_vinfo
.v_depth
= 8;
2268 new_vinfo
.v_rowbytes
= 0x8000;
2271 #endif /* __i386__ */
2273 if (!new_vinfo
.v_physaddr
) /* Check to see if we have a framebuffer */
2275 kprintf("initialize_screen: No video - forcing serial mode\n"); /* (BRINGUP) */
2276 new_vinfo
.v_depth
= 0; /* vc routines are nop */
2277 (void)switch_to_serial_console(); /* Switch into serial mode */
2278 gc_graphics_boot
= FALSE
; /* Say we are not in graphics mode */
2279 disableConsoleOutput
= FALSE
; /* Allow printfs to happen */
2285 * Note that for the first time only, boot_vinfo->v_baseAddr is physical.
2288 if (kernel_map
!= VM_MAP_NULL
) /* If VM is up, we are given a virtual address */
2290 fbppage
= pmap_find_phys(kernel_pmap
, (addr64_t
)boot_vinfo
->v_baseAddr
); /* Get the physical address of frame buffer */
2291 if(!fbppage
) /* Did we find it? */
2293 panic("initialize_screen: Strange framebuffer - addr = %08X\n", (uint32_t)boot_vinfo
->v_baseAddr
);
2295 new_vinfo
.v_physaddr
= (fbppage
<< 12) | (boot_vinfo
->v_baseAddr
& PAGE_MASK
); /* Get the physical address */
2298 if (boot_vinfo
->v_length
!= 0)
2299 fbsize
= round_page_32(boot_vinfo
->v_length
);
2301 fbsize
= round_page_32(new_vinfo
.v_height
* new_vinfo
.v_rowbytes
); /* Remember size */
2304 if ((lastVideoPhys
!= new_vinfo
.v_physaddr
) || (fbsize
> lastVideoSize
)) /* Did framebuffer change location or get bigger? */
2308 flags
= (new_vinfo
.v_type
== VGA_TEXT_MODE
) ? VM_WIMG_IO
: VM_WIMG_WCOMB
;
2312 newVideoVirt
= io_map_spec((vm_offset_t
)new_vinfo
.v_physaddr
, fbsize
, flags
); /* Allocate address space for framebuffer */
2316 if (newVideoVirt
!= 0)
2317 new_vinfo
.v_baseaddr
= newVideoVirt
+ boot_vinfo
->v_offset
; /* Set the new framebuffer address */
2319 new_vinfo
.v_baseaddr
= lastVideoVirt
+ boot_vinfo
->v_offset
; /* Set the new framebuffer address */
2321 /* Update the vinfo structure atomically with respect to the vc_progress task if running */
2324 simple_lock(&vc_progress_lock
);
2326 simple_unlock(&vc_progress_lock
);
2333 // If we changed the virtual address, remove the old mapping
2334 if (newVideoVirt
!= 0)
2336 if (lastVideoVirt
) /* Was the framebuffer mapped before? */
2339 if(lastVideoMapped
) /* Was this not a special pre-VM mapping? */
2342 pmap_remove(kernel_pmap
, trunc_page_64(lastVideoVirt
),
2343 round_page_64(lastVideoVirt
+ lastVideoSize
)); /* Toss mappings */
2345 if(lastVideoMapped
) /* Was this not a special pre-VM mapping? */
2347 kmem_free(kernel_map
, lastVideoVirt
, lastVideoSize
); /* Toss kernel addresses */
2350 lastVideoPhys
= new_vinfo
.v_physaddr
; /* Remember the framebuffer address */
2351 lastVideoSize
= fbsize
; /* Remember the size */
2352 lastVideoVirt
= newVideoVirt
; /* Remember the virtual framebuffer address */
2353 lastVideoMapped
= (NULL
!= kernel_map
);
2357 if ( (vinfo
.v_type
== VGA_TEXT_MODE
) )
2359 // Text mode setup by the booter.
2361 gc_ops
.initialize
= tc_initialize
;
2362 gc_ops
.enable
= tc_enable
;
2363 gc_ops
.paint_char
= tc_paint_char
;
2364 gc_ops
.clear_screen
= tc_clear_screen
;
2365 gc_ops
.scroll_down
= tc_scroll_down
;
2366 gc_ops
.scroll_up
= tc_scroll_up
;
2367 gc_ops
.hide_cursor
= tc_hide_cursor
;
2368 gc_ops
.show_cursor
= tc_show_cursor
;
2369 gc_ops
.update_color
= tc_update_color
;
2372 #endif /* __i386__ */
2374 // Graphics mode setup by the booter.
2376 gc_ops
.initialize
= vc_initialize
;
2377 gc_ops
.enable
= vc_enable
;
2378 gc_ops
.paint_char
= vc_paint_char
;
2379 gc_ops
.scroll_down
= vc_scroll_down
;
2380 gc_ops
.scroll_up
= vc_scroll_up
;
2381 gc_ops
.clear_screen
= vc_clear_screen
;
2382 gc_ops
.hide_cursor
= vc_reverse_cursor
;
2383 gc_ops
.show_cursor
= vc_reverse_cursor
;
2384 gc_ops
.update_color
= vc_update_color
;
2387 gc_initialize(&vinfo
);
2389 #ifdef GRATEFULDEBUGGER
2390 GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re-initialize GratefulDeb */
2391 #endif /* GRATEFULDEBUGGER */
2396 case kPEGraphicsMode
:
2397 panicDialogDesired
= TRUE
;
2398 gc_graphics_boot
= TRUE
;
2399 gc_desire_text
= FALSE
;
2403 panicDialogDesired
= FALSE
;
2404 gc_graphics_boot
= FALSE
;
2407 case kPEAcquireScreen
:
2408 if ( gc_acquired
) break;
2409 graphics_now
= gc_graphics_boot
&& !gc_desire_text
;
2410 vc_progress_set( graphics_now
, kProgressAcquireDelay
);
2411 gc_enable( !graphics_now
);
2413 gc_desire_text
= FALSE
;
2416 case kPEEnableScreen
:
2421 if ( console_is_serial() ) break;
2423 panicDialogDesired
= FALSE
;
2424 if ( gc_acquired
== FALSE
)
2426 gc_desire_text
= TRUE
;
2429 if ( gc_graphics_boot
== FALSE
) break;
2431 vc_progress_set( FALSE
, 0 );
2435 case kPEDisableScreen
:
2439 case kPEReleaseScreen
:
2440 gc_acquired
= FALSE
;
2441 gc_desire_text
= FALSE
;
2443 vc_progress_set( FALSE
, 0 );
2446 #ifdef GRATEFULDEBUGGER
2447 GratefulDebInit(0); /* Stop grateful debugger */
2448 #endif /* GRATEFULDEBUGGER */
2451 #ifdef GRATEFULDEBUGGER
2452 if ( boot_vinfo
) GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re initialize GratefulDeb */
2453 #endif /* GRATEFULDEBUGGER */
2456 void vcattach(void); /* XXX gcc 4 warning cleanup */
2461 vm_initialized
= TRUE
;
2463 if ( gc_graphics_boot
== FALSE
)
2469 initialize_screen(NULL
, kPEReleaseScreen
);
2472 initialize_screen(NULL
, kPEAcquireScreen
);
2474 for ( index
= 0 ; index
< msgbufp
->msg_bufx
; index
++ )
2476 vcputc( 0, 0, msgbufp
->msg_bufc
[index
] );
2478 if ( msgbufp
->msg_bufc
[index
] == '\n' )
2480 vcputc( 0, 0,'\r' );