summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/ofw
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2005-02-25 02:29:01 +0000
committergrehan <grehan@FreeBSD.org>2005-02-25 02:29:01 +0000
commit5ffc2173f35b96ccf3b6b5afbf736bc3de3bf255 (patch)
tree84862a744904ba239d0943cc8d350eac9da11842 /sys/powerpc/ofw
parentcc77e8b9db95d2f5596ab8bd8d96592b7c80f9c6 (diff)
downloadFreeBSD-src-5ffc2173f35b96ccf3b6b5afbf736bc3de3bf255.zip
FreeBSD-src-5ffc2173f35b96ccf3b6b5afbf736bc3de3bf255.tar.gz
Mods for Xorg server:
- store assigned PCI addresses at cninit time for later mmap range check - implement set_border to scrub X remnants when switching back to VTYs - implement mmap, only allowing addresses within the range of the console adapter.
Diffstat (limited to 'sys/powerpc/ofw')
-rw-r--r--sys/powerpc/ofw/ofw_syscons.c114
-rw-r--r--sys/powerpc/ofw/ofw_syscons.h5
2 files changed, 113 insertions, 6 deletions
diff --git a/sys/powerpc/ofw/ofw_syscons.c b/sys/powerpc/ofw/ofw_syscons.c
index 97f122a..9537313 100644
--- a/sys/powerpc/ofw/ofw_syscons.c
+++ b/sys/powerpc/ofw/ofw_syscons.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/kernel.h>
+#include <sys/sysctl.h>
#include <sys/limits.h>
#include <sys/conf.h>
#include <sys/cons.h>
@@ -52,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <dev/syscons/syscons.h>
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_pci.h>
#include <powerpc/ofw/ofw_syscons.h>
#include <machine/nexusvar.h>
@@ -132,9 +134,11 @@ static video_switch_t ofwfbvidsw = {
*/
static vi_blank_display_t ofwfb_blank_display8;
static vi_putc_t ofwfb_putc8;
+static vi_set_border_t ofwfb_set_border8;
static vi_blank_display_t ofwfb_blank_display32;
static vi_putc_t ofwfb_putc32;
+static vi_set_border_t ofwfb_set_border32;
VIDEO_DRIVER(ofwfb, ofwfbvidsw, ofwfb_configure);
@@ -209,6 +213,7 @@ ofwfb_configure(int flags)
phandle_t node;
int depth;
int disable;
+ int len;
char type[16];
static int done = 0;
@@ -230,14 +235,16 @@ ofwfb_configure(int flags)
if (strcmp(type, "display") != 0)
return (0);
- /* Only support 8-bit framebuffers */
+ /* Only support 8 and 32-bit framebuffers */
OF_getprop(node, "depth", &depth, sizeof(depth));
if (depth == 8) {
sc->sc_blank = ofwfb_blank_display8;
sc->sc_putc = ofwfb_putc8;
+ sc->sc_set_border = ofwfb_set_border8;
} else if (depth == 32) {
sc->sc_blank = ofwfb_blank_display32;
sc->sc_putc = ofwfb_putc32;
+ sc->sc_set_border = ofwfb_set_border32;
} else
return (0);
@@ -254,6 +261,22 @@ ofwfb_configure(int flags)
*/
OF_getprop(node, "address", &sc->sc_addr, sizeof(sc->sc_addr));
+ /*
+ * Get the PCI addresses of the adapter. The node may be the
+ * child of the PCI device: in that case, try the parent for
+ * the assigned-addresses property.
+ */
+ len = OF_getprop(node, "assigned-addresses", sc->sc_pciaddrs,
+ sizeof(sc->sc_pciaddrs));
+ if (len == -1) {
+ len = OF_getprop(OF_parent(node), "assigned-addresses", sc->sc_pciaddrs,
+ sizeof(sc->sc_pciaddrs));
+ }
+
+ if (len != -1) {
+ sc->sc_num_pciaddrs = len / sizeof(struct ofw_pci_register);
+ }
+
ofwfb_init(0, &sc->sc_va, 0);
return (0);
@@ -402,7 +425,7 @@ ofwfb_load_font(video_adapter_t *adp, int page, int size, u_char *data,
static int
ofwfb_show_font(video_adapter_t *adp, int page)
{
- TODO;
+
return (0);
}
@@ -421,13 +444,66 @@ ofwfb_load_palette(video_adapter_t *adp, u_char *palette)
}
static int
-ofwfb_set_border(video_adapter_t *adp, int border)
+ofwfb_set_border8(video_adapter_t *adp, int border)
{
- /* TODO; */
+ struct ofwfb_softc *sc;
+ int i, j;
+ uint8_t *addr;
+ uint8_t bground;
+
+ sc = (struct ofwfb_softc *)adp;
+
+ bground = ofwfb_background(border);
+
+ /* Set top margin */
+ addr = (uint8_t *) sc->sc_addr;
+ for (i = 0; i < sc->sc_ymargin; i++) {
+ for (j = 0; j < sc->sc_width; j++) {
+ *(addr + j) = bground;
+ }
+ addr += sc->sc_stride;
+ }
+
+ /* bottom margin */
+ addr = (uint8_t *) sc->sc_addr + (sc->sc_height - sc->sc_ymargin)*sc->sc_stride;
+ for (i = 0; i < sc->sc_ymargin; i++) {
+ for (j = 0; j < sc->sc_width; j++) {
+ *(addr + j) = bground;
+ }
+ addr += sc->sc_stride;
+ }
+
+ /* remaining left and right borders */
+ addr = (uint8_t *) sc->sc_addr + sc->sc_ymargin*sc->sc_stride;
+ for (i = 0; i < sc->sc_height - 2*sc->sc_xmargin; i++) {
+ for (j = 0; j < sc->sc_xmargin; j++) {
+ *(addr + j) = bground;
+ *(addr + j + sc->sc_width - sc->sc_xmargin) = bground;
+ }
+ addr += sc->sc_stride;
+ }
+
return (0);
}
static int
+ofwfb_set_border32(video_adapter_t *adp, int border)
+{
+ /* XXX Be lazy for now and blank entire screen */
+ return (ofwfb_blank_display32(adp, border));
+}
+
+static int
+ofwfb_set_border(video_adapter_t *adp, int border)
+{
+ struct ofwfb_softc *sc;
+
+ sc = (struct ofwfb_softc *)adp;
+
+ return ((*sc->sc_set_border)(adp, border));
+}
+
+static int
ofwfb_save_state(video_adapter_t *adp, void *p, size_t size)
{
TODO;
@@ -518,8 +594,34 @@ static int
ofwfb_mmap(video_adapter_t *adp, vm_offset_t offset, vm_paddr_t *paddr,
int prot)
{
- TODO;
- return (0);
+ struct ofwfb_softc *sc;
+ int i;
+
+ sc = (struct ofwfb_softc *)adp;
+
+ if (sc->sc_num_pciaddrs == 0)
+ return (ENOMEM);
+
+ /*
+ * Make sure the requested address lies within the PCI device's assigned addrs
+ */
+ for (i = 0; i < sc->sc_num_pciaddrs; i++)
+ if (offset >= sc->sc_pciaddrs[i].phys_lo &&
+ offset < (sc->sc_pciaddrs[i].phys_lo + sc->sc_pciaddrs[i].size_lo)) {
+ *paddr = offset;
+ return (0);
+ }
+
+ /*
+ * This might be a legacy VGA mem request: if so, just point it at the
+ * framebuffer, since it shouldn't be touched
+ */
+ if (offset < sc->sc_stride*sc->sc_height) {
+ *paddr = sc->sc_addr + offset;
+ return (0);
+ }
+
+ return (EINVAL);
}
static int
diff --git a/sys/powerpc/ofw/ofw_syscons.h b/sys/powerpc/ofw/ofw_syscons.h
index 05b21be..af33c52 100644
--- a/sys/powerpc/ofw/ofw_syscons.h
+++ b/sys/powerpc/ofw/ofw_syscons.h
@@ -51,6 +51,11 @@ struct ofwfb_softc {
vi_blank_display_t *sc_blank;
vi_putc_t *sc_putc;
+ vi_set_border_t *sc_set_border;
+
+#define OFWSC_MAXADDR 8
+ int sc_num_pciaddrs;
+ struct ofw_pci_register sc_pciaddrs[OFWSC_MAXADDR];
};
#endif
OpenPOWER on IntegriCloud