[OpenBIOS] [PATCH 04/14] pci/vga: move PCI framebuffer map functions info Forth

Mark Cave-Ayland mark.cave-ayland at ilande.co.uk
Thu Aug 8 00:51:08 CEST 2013


Here we move the code to map the PCI framebuffer into Forth. This is done by
introducing a "pci-map-in" word on the /pci node to enable Forth code to
perform memory-mapping as required.

This is a slight departure from the specification which requires a "map-in"
word, but this is because the OpenBIOS PCI bus enumerator *always* configures
BARs regardless of whether or not an FCode payload is detected. In order to
avoid having to rewrite the bus enumeration code in Forth, we instead create
a "pci-bar>pci-region" word which takes the BAR register as a parameter and
returns the configured BAR bus address and size. This can then be passed to
the "pci-map-in" word in order to do the work.

Finally with this in place, we can remove the mapping that takes place in
vga_vbe_init().

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
 openbios-devel/drivers/pci.c     |   56 ++++++++++++++++++++++-----
 openbios-devel/drivers/pci.fs    |   77 ++++++++++++++++++++++++++++++++++++++
 openbios-devel/drivers/vga.fs    |   40 +++++++++++++++-----
 openbios-devel/drivers/vga_vbe.c |    8 ----
 4 files changed, 154 insertions(+), 27 deletions(-)

diff --git a/openbios-devel/drivers/pci.c b/openbios-devel/drivers/pci.c
index 3f37fd8..368d7b5 100644
--- a/openbios-devel/drivers/pci.c
+++ b/openbios-devel/drivers/pci.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 #include "libopenbios/bindings.h"
+#include "libopenbios/ofmem.h"
 #include "kernel/kernel.h"
 #include "drivers/pci.h"
 #include "libc/byteorder.h"
@@ -25,6 +26,7 @@
 #include "drivers/drivers.h"
 #include "drivers/vga.h"
 #include "packages/video.h"
+#include "libopenbios/video.h"
 #include "timer.h"
 #include "pci.h"
 #include "pci_database.h"
@@ -139,6 +141,15 @@ static void dump_reg_property(const char* description, int nreg, u32 *reg)
 }
 #endif
 
+static unsigned long pci_bus_addr_to_host_addr(uint32_t ba)
+{
+#ifdef CONFIG_SPARC64
+    return arch->cfg_data + (unsigned long)ba;
+#else
+    return (unsigned long)ba;
+#endif
+}
+
 static void
 ob_pci_open(int *idx)
 {
@@ -330,12 +341,48 @@ ob_pci_encode_unit(int *idx)
 	        ss, dev, fn, buf);
 }
 
+/* ( pci-addr.lo pci-addr.hi size -- virt ) */
+
+static void
+ob_pci_map_in(int *idx)
+{
+	phys_addr_t phys;
+	uint32_t ba;
+	ucell size, virt;
+
+	PCI_DPRINTF("ob_pci_bar_map_in idx=%p\n", idx);
+
+	size = POP();
+	POP();
+	ba = POP();
+
+	phys = pci_bus_addr_to_host_addr(ba);
+
+#if defined(CONFIG_OFMEM)
+	ofmem_claim_phys(phys, size, 0);
+
+#if defined(CONFIG_SPARC64)
+	/* Fix virtual address on SPARC64 somewhere else */
+	virt = ofmem_claim_virt(0xfe000000ULL, size, 0);
+#else
+	virt = ofmem_claim_virt(phys, size, 0);
+#endif
+
+	ofmem_map(phys, virt, size, ofmem_arch_io_translation_mode(phys));
+
+	PUSH(virt);
+#else
+	PUSH(phys);
+#endif
+}
+
 NODE_METHODS(ob_pci_bus_node) = {
 	{ NULL,			ob_pci_initialize	},
 	{ "open",		ob_pci_open		},
 	{ "close",		ob_pci_close		},
 	{ "decode-unit",	ob_pci_decode_unit	},
 	{ "encode-unit",	ob_pci_encode_unit	},
+	{ "pci-map-in",		ob_pci_map_in		},
 };
 
 NODE_METHODS(ob_pci_simple_node) = {
@@ -485,15 +532,6 @@ static void pci_host_set_ranges(const pci_config_t *config)
 	set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0]));
 }
 
-static unsigned long pci_bus_addr_to_host_addr(uint32_t ba)
-{
-#ifdef CONFIG_SPARC64
-    return arch->cfg_data + (unsigned long)ba;
-#else
-    return (unsigned long)ba;
-#endif
-}
-
 int host_config_cb(const pci_config_t *config)
 {
 	//XXX this overrides "reg" property
diff --git a/openbios-devel/drivers/pci.fs b/openbios-devel/drivers/pci.fs
index e8d25a0..563b652 100644
--- a/openbios-devel/drivers/pci.fs
+++ b/openbios-devel/drivers/pci.fs
@@ -12,4 +12,81 @@
   rot encode-int encode+ 
   ;
 
+\ Get region offset for BAR reg
+: pci-bar-offset@ ( bar-reg -- off.lo off.hi -1 | 0 )
+  " reg" active-package get-package-property 0= if
+    begin
+      decode-phys    \ ( reg prop prop-len phys.lo phys.mid phys.hi )
+      ff and 5 pick = if
+        >r >r 3drop r> r>
+        -1 exit
+      else
+        2drop
+      then
+      \ Drop the size as we don't need it
+      decode-int drop decode-int drop
+      dup 0=
+    until
+    3drop
+    0 exit
+  else
+    0
+  then
+  ;
+
+\ Get region size for BAR reg
+: pci-bar-size@ ( bar-reg -- size )
+  " reg" active-package get-package-property 0= if
+    begin
+      decode-phys    \ ( reg prop prop-len phys.lo phys.mid phys.hi )
+      ff and 5 pick = if
+        2drop decode-int drop
+        decode-int
+        >r 3drop r>
+        exit
+      else
+        2drop decode-int drop
+        decode-int drop
+      then
+      dup 0=
+    until
+    3drop
+    0    \ default size of 0 if BAR not found
+  then
+  ;
+
+\ Get base address for configured BAR reg
+: pci-bar-base@ ( bar-reg -- addr.lo addr.hi -1 | 0 )
+  " assigned-addresses" active-package get-package-property 0= if
+    begin
+      decode-phys    \ ( reg prop prop-len phys.lo phys.mid phys.hi )
+      ff and 5 pick = if
+        >r >r 3drop r> r>
+        -1 exit
+      else
+        2drop
+      then
+      \ Drop the size as we don't need it
+      decode-int drop decode-int drop
+      dup 0=
+    until
+    3drop
+    0 exit
+  else
+    0
+  then
+  ;
+
+\ Get PCI bus address and size for configured BAR reg
+: pci-bar>pci-region  ( bar-reg -- addr.lo addr.hi size )
+  dup
+  >r pci-bar-offset@ if
+    swap r@ pci-bar-base@ if
+      swap d+
+    then
+    swap r@ pci-bar-size@
+  then
+  r> drop
+  ;
+
 [THEN]
diff --git a/openbios-devel/drivers/vga.fs b/openbios-devel/drivers/vga.fs
index 43c8819..bf2ae60 100644
--- a/openbios-devel/drivers/vga.fs
+++ b/openbios-devel/drivers/vga.fs
@@ -106,6 +106,22 @@ h# 1 constant VBE_DISPI_ENABLED
 ;
 
 \
+\ PCI
+\
+
+" pci-bar>pci-region" (find-xt) value pci-bar>pci-region-xt
+: pci-bar>pci-region pci-bar>pci-region-xt execute ;
+
+h# 10 constant cfg-bar0    \ Framebuffer BAR
+-1 value fb-addr
+
+: map-fb ( -- )
+  cfg-bar0 pci-bar>pci-region   \ ( pci-addr.lo pci-addr.hi size )
+  " pci-map-in" $call-parent
+  to fb-addr
+;
+
+\
 \ Publically visible words
 \
 
@@ -165,23 +181,27 @@ headerless
 \
 
 : qemu-vga-driver-install ( -- )
-  openbios-video-addr to frame-buffer-adr
-  default-font set-font
+  fb-addr -1 = if
+    map-fb fb-addr to frame-buffer-adr
+    default-font set-font
 
-  frame-buffer-adr encode-int " address" property
-  openbios-video-width encode-int " width" property
-  openbios-video-height encode-int " height" property
-  depth-bits encode-int " depth" property
-  line-bytes encode-int " linebytes" property
+    frame-buffer-adr encode-int " address" property
 
-  openbios-video-width openbios-video-height over char-width / over char-height /
-  fb8-install
+    openbios-video-width openbios-video-height over char-width / over char-height /
+    fb8-install
+  then
 ;
 
 : qemu-vga-driver-init
+
   vbe-init
+  openbios-video-width encode-int " width" property
+  openbios-video-height encode-int " height" property
+  depth-bits encode-int " depth" property
+  line-bytes encode-int " linebytes" property
+
   ['] qemu-vga-driver-install is-install
-  ;
+;
 
 qemu-vga-driver-init
 
diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c
index 8c224d6..2f845e7 100644
--- a/openbios-devel/drivers/vga_vbe.c
+++ b/openbios-devel/drivers/vga_vbe.c
@@ -98,12 +98,4 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size,
 				     p + 8, size);
 		}
 	}
-
-#if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI)
-        size = ((VIDEO_DICT_VALUE(video.h) * VIDEO_DICT_VALUE(video.rb))  + 0xfff) & ~0xfff;
-
-	ofmem_claim_phys( video.mphys, size, 0 );
-	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
 }
-- 
1.7.10.4




More information about the OpenBIOS mailing list