[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