[OpenBIOS] [PATCH 13/20] video_common.c: move colour palette code into individual devices

Mark Cave-Ayland mark.cave-ayland at ilande.co.uk
Sat Jun 15 10:38:51 CEST 2013


Instead if having a large #ifdef .. #endif section in video_set_color(), move
the device-specific hardware setters into each display device package.

To do this, we keep track of the display ihandle in the video structure and
use it to invoke the low-level hardware setter routine (and optional palette
refresh) if required.

Also since the display-ih isn't called until is-install, defer the colour
palette initialisation from init_video() to is-install.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
 openbios-devel/arch/sparc32/console.c      |   17 ++++++++++
 openbios-devel/drivers/sbus.c              |    1 +
 openbios-devel/drivers/vga_vbe.c           |   18 +++++++++++
 openbios-devel/forth/device/display.fs     |   25 +++++++++++++++
 openbios-devel/include/drivers/drivers.h   |    1 +
 openbios-devel/include/libopenbios/video.h |    1 +
 openbios-devel/libopenbios/video_common.c  |   46 ++++++++++++++--------------
 openbios-devel/packages/molvideo.c         |   19 +++++++++---
 8 files changed, 101 insertions(+), 27 deletions(-)

diff --git a/openbios-devel/arch/sparc32/console.c b/openbios-devel/arch/sparc32/console.c
index c986e2b..53aa77f 100644
--- a/openbios-devel/arch/sparc32/console.c
+++ b/openbios-devel/arch/sparc32/console.c
@@ -11,6 +11,7 @@
 #include "openbios.h"
 #include "libopenbios/console.h"
 #include "libopenbios/ofmem.h"
+#include "libopenbios/video.h"
 
 void cls(void);
 
@@ -41,6 +42,22 @@ void tcx_init(uint64_t base)
     dac = (uint32_t *)ofmem_map_io(base + DAC_BASE, DAC_SIZE);
 }
 
+/* ( r g b index -- ) */
+void tcx_hw_set_color(void)
+{
+    int index = POP();
+    int b = POP();
+    int g = POP();
+    int r = POP();
+
+    if( VIDEO_DICT_VALUE(video.depth) == 8 ) {
+        dac[0] = index << 24;
+        dac[1] = r << 24; // Red
+        dac[1] = g << 24; // Green
+        dac[1] = b << 24; // Blue
+    }
+}
+
 #endif
 
 /* ******************************************************************
diff --git a/openbios-devel/drivers/sbus.c b/openbios-devel/drivers/sbus.c
index d171018..fbac2d7 100644
--- a/openbios-devel/drivers/sbus.c
+++ b/openbios-devel/drivers/sbus.c
@@ -329,6 +329,7 @@ ob_tcx_init(unsigned int slot, const char *path)
         fword("property");
     }
 
+    bind_func("hw-set-color", tcx_hw_set_color);
     feval("['] qemu-tcx-driver-init is-install");
 
     chosen = find_dev("/chosen");
diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c
index 884c261..33765b6 100644
--- a/openbios-devel/drivers/vga_vbe.c
+++ b/openbios-devel/drivers/vga_vbe.c
@@ -103,6 +103,22 @@ void vga_vbe_set_mode(int width, int height, int depth)
         vga_build_rgb_palette();
 }
 
+/* Low-level Forth accessor to update VGA color registers */
+
+/* ( r g b index -- ) */
+static
+void vga_hw_set_color(void)
+{
+    int index = POP();
+    int b = POP();
+    int g = POP();
+    int r = POP();
+
+    vga_set_color(index, (r & 0xff),
+        (g & 0xff),
+        (b & 0xff));
+}
+
 void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size,
                   unsigned long rom, uint32_t rom_size)
 {
@@ -128,6 +144,8 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size,
     ph = get_cur_dev();
 #endif
 
+	bind_func("hw-set-color", vga_hw_set_color);
+
 	set_int_property(ph, "width", VIDEO_DICT_VALUE(video.w));
 	set_int_property(ph, "height", VIDEO_DICT_VALUE(video.h));
 	set_int_property(ph, "depth", VIDEO_DICT_VALUE(video.depth));
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs
index cf709fa..ae7bdeb 100644
--- a/openbios-devel/forth/device/display.fs
+++ b/openbios-devel/forth/device/display.fs
@@ -48,6 +48,7 @@ create color-palette 100 cells allot
 2 value font-spacing
 0 value depth-bits
 0 value line-bytes
+0 value display-ih
 
 \ internal values read from QEMU firmware interface
 0 value qemu-video-addr
@@ -353,6 +354,8 @@ defer fb8-invertrect
   0 to inverse? 
   0 to inverse-screen?
 
+  my-self to display-ih
+
   \ set defer functions to 8bit versions
 
   ['] fb8-draw-character to draw-character
@@ -375,6 +378,28 @@ defer fb8-invertrect
   then
   to foreground-color to background-color
 
+  \ setup palette
+  10101 ['] color-palette cell+ ff 0 do
+    dup 2 pick i * swap ! cell+
+  loop 2drop
+
+  \ special background color
+  ffffcc ['] color-palette cell+ fe cells + !
+
+  \ load palette onto the hardware
+  ['] color-palette cell+ ff 0 do
+    dup @ ff0000 and d# 16 rshift
+    1 pick @ ff00 and d# 8 rshift
+    2 pick @ ff and
+    i
+    s" hw-set-color" $find if
+      execute
+    else
+      2drop
+    then
+    cell+
+  loop drop
+
   \ ... but let's override with some better defaults
   fe to background-color
   0 to foreground-color
diff --git a/openbios-devel/include/drivers/drivers.h b/openbios-devel/include/drivers/drivers.h
index d139ace..d041e81 100644
--- a/openbios-devel/include/drivers/drivers.h
+++ b/openbios-devel/include/drivers/drivers.h
@@ -47,6 +47,7 @@ int ob_sbus_init(uint64_t base, int machine_id);
 
 /* arch/sparc32/console.c */
 void tcx_init(uint64_t base);
+void tcx_hw_set_color(void);
 void kbd_init(uint64_t base);
 #endif
 #ifdef CONFIG_DRIVER_IDE
diff --git a/openbios-devel/include/libopenbios/video.h b/openbios-devel/include/libopenbios/video.h
index bcd024e..cf2b5db 100644
--- a/openbios-devel/include/libopenbios/video.h
+++ b/openbios-devel/include/libopenbios/video.h
@@ -30,6 +30,7 @@ void video_fill_rect(void);
 extern struct video_info {
     int has_video;
 
+    volatile ihandle_t *ih;
     volatile phys_addr_t mphys;
     volatile ucell *mvirt;
     volatile ucell *rb, *w, *h, *depth;
diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c
index 9d45e69..ca2826e 100644
--- a/openbios-devel/libopenbios/video_common.c
+++ b/openbios-devel/libopenbios/video_common.c
@@ -46,27 +46,30 @@ video_get_color( int col_ind )
 void
 video_set_color( int ind, unsigned long color )
 {
+	xt_t hw_xt = 0;
+
 	if( !video.has_video || ind < 0 || ind > 255 )
 		return;
 	video.pal[ind] = color;
 
-#ifdef CONFIG_MOL
-	if( VIDEO_DICT_VALUE(video.depth) == 8 )
-		OSI_SetColor( ind, color );
-#elif defined(CONFIG_SPARC32)
-#if defined(CONFIG_DEBUG_CONSOLE_VIDEO)
-	if( VIDEO_DICT_VALUE(video.depth) == 8 ) {
-            dac[0] = ind << 24;
-            dac[1] = ((color >> 16) & 0xff) << 24; // Red
-            dac[1] = ((color >> 8) & 0xff) << 24; // Green
-            dac[1] = (color & 0xff) << 24; // Blue
-        }
-#endif
-#else
-	vga_set_color(ind, ((color >> 16) & 0xff),
-			   ((color >> 8) & 0xff),
-			   (color & 0xff));
-#endif
+	/* Call the low-level hardware setter in the
+	   display package */
+	hw_xt = find_ih_method("hw-set-color", VIDEO_DICT_VALUE(video.ih));
+	if (hw_xt) {
+		PUSH((color >> 16) & 0xff);  // Red
+		PUSH((color >> 8) & 0xff);  // Green
+		PUSH(color & 0xff);  // Blue
+		PUSH(ind);
+		PUSH(hw_xt);
+		fword("execute");
+	}
+
+	/* Call the low-level palette update if required */
+	hw_xt = find_ih_method("hw-refresh-palette", VIDEO_DICT_VALUE(video.ih));
+	if (hw_xt) {
+		PUSH(hw_xt);
+		fword("execute");
+	}
 }
 
 /* ( fbaddr maskaddr width height fgcolor bgcolor -- ) */
@@ -219,6 +222,9 @@ void setup_video(phys_addr_t phys, ucell virt)
 
 	video.mphys = phys;
 
+	feval("['] display-ih cell+");
+	video.ih = cell2pointer(POP());
+
 	feval("['] qemu-video-addr cell+");
 	video.mvirt = cell2pointer(POP());
 	feval("['] qemu-video-width cell+");
@@ -277,7 +283,6 @@ void setup_video(phys_addr_t phys, ucell virt)
 void
 init_video(void)
 {
-        int i;
 #if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI)
         int size;
 #endif
@@ -306,9 +311,4 @@ init_video(void)
 	ofmem_claim_virt( VIDEO_DICT_VALUE(video.mvirt), size, 0 );
 	ofmem_map( video.mphys, VIDEO_DICT_VALUE(video.mvirt), size, ofmem_arch_io_translation_mode(video.mphys) );
 #endif
-
-	for( i=0; i<256; i++ )
-		video_set_color( i, i * 0x010101 );
-
-	video_set_color( 254, 0xffffcc );
 }
diff --git a/openbios-devel/packages/molvideo.c b/openbios-devel/packages/molvideo.c
index 742f516..24cc2fd 100644
--- a/openbios-devel/packages/molvideo.c
+++ b/openbios-devel/packages/molvideo.c
@@ -31,15 +31,24 @@
 
 DECLARE_NODE( video, 0, 0, "Tdisplay" );
 
+#ifdef CONFIG_MOL
 static void
 molvideo_refresh_palette( void )
 {
-#ifdef CONFIG_MOL
+
 	if( VIDEO_DICT_VALUE(video.depth) == 8 )
 		OSI_RefreshPalette();
-#endif
 }
 
+static void
+molvideo_hw_set_color( void )
+{
+
+	if( VIDEO_DICT_VALUE(video.depth) == 8 )
+		OSI_SetColor( ind, color );
+}
+#endif
+
 /* ( -- width height ) (?) */
 static void
 molvideo_dimensions( void )
@@ -61,7 +70,6 @@ molvideo_set_colors( void )
 		unsigned long col = (p[0] << 16) | (p[1] << 8) | p[2];
 		video_set_color( i + start, col );
 	}
-	molvideo_refresh_palette();
 }
 
 /* ( r g b index -- ) */
@@ -75,7 +83,6 @@ molvideo_color_bang( void )
 	unsigned long col = ((r << 16) & 0xff0000) | ((g << 8) & 0x00ff00) | (b & 0xff);
 	/* printk("color!: %08lx %08lx %08lx %08lx\n", r, g, b, index ); */
 	video_set_color( index, col );
-	molvideo_refresh_palette();
 }
 
 /* ( color_ind x y width height -- ) (?) */
@@ -143,6 +150,10 @@ molvideo_startup_splash( void )
 
 
 NODE_METHODS( video ) = {
+#ifdef CONFIG_MOL
+	{"hw-set-color",	molvideo_hw_set_color   },
+	{"hw-refresh-palette",	molvideo_refresh_palette},
+#endif
 	{"dimensions",		molvideo_dimensions	},
 	{"set-colors",		molvideo_set_colors	},
 	{"fill-rectangle",	molvideo_fill_rect	},
-- 
1.7.10.4




More information about the OpenBIOS mailing list