Page MenuHomeFreeBSD

D30626.1783623689.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D30626.1783623689.diff

Index: sys/dev/vt/hw/ofwfb/ofwfb.c
===================================================================
--- sys/dev/vt/hw/ofwfb/ofwfb.c
+++ sys/dev/vt/hw/ofwfb/ofwfb.c
@@ -61,7 +61,8 @@
uint32_t vendor_id;
};
-#define PCI_VENDOR_ID_NVIDIA 0x10de
+#define PCI_VID_NVIDIA 0x10de /* NVIDIA Corporation */
+#define PCI_VID_ASPEED 0x1a03 /* ASPEED Technology, Inc. */
static void ofwfb_initialize(struct vt_device *vd);
static vd_probe_t ofwfb_probe;
@@ -90,6 +91,8 @@
static struct ofwfb_softc ofwfb_conssoftc;
VT_DRIVER_DECLARE(vt_ofwfb, vt_ofwfb_driver);
+uint64_t asmedia_fb_address(phandle_t node);
+
static int
ofwfb_probe(struct vt_device *vd)
{
@@ -297,6 +300,91 @@
#endif
}
+static uint64_t
+parse_ranges(phandle_t pcinode)
+{
+ if (!OF_hasprop(pcinode, "ranges")){
+ return -1;
+ }
+
+ struct simplebus_range {
+ uint64_t bus;
+ uint64_t host;
+ uint64_t size;
+ };
+
+ struct simplebus_range *ranges;
+ int nranges;
+ pcell_t acells, scells;
+
+ int host_address_cells;
+ cell_t *base_ranges;
+
+ ssize_t nbase_ranges;
+ int i, j, k;
+
+ if (OF_getencprop(pcinode, "#address-cells", &acells, sizeof(acells)) !=
+ sizeof(acells))
+ return -1;
+
+ if (OF_getencprop(pcinode, "#size-cells", &scells, sizeof(scells)) !=
+ sizeof(scells))
+ return -1;
+
+ if (OF_searchencprop(OF_parent(pcinode), "#address-cells",
+ &host_address_cells, sizeof(host_address_cells)) !=
+ sizeof(host_address_cells))
+ return -1;
+
+ nbase_ranges = OF_getproplen(pcinode, "ranges");
+ nranges = nbase_ranges / sizeof(cell_t) / (acells + host_address_cells + scells);
+
+ struct simplebus_range buf[4];
+ ranges = (struct simplebus_range *)&buf;
+
+ cell_t buf2[64];
+ base_ranges = (cell_t *)&buf2;
+
+ OF_getencprop(pcinode, "ranges", base_ranges, nbase_ranges);
+ for (i = 0, j = 0; i < nranges; i++) {
+ ranges[i].bus = 0;
+ for (k = 0; k < acells; k++) {
+ ranges[i].bus <<= 32;
+ ranges[i].bus |= base_ranges[j++];
+ }
+
+ ranges[i].host = 0;
+ for (k = 0; k < host_address_cells; k++) {
+ ranges[i].host <<= 32;
+ ranges[i].host |= base_ranges[j++];
+ }
+ ranges[i].size = 0;
+ for (k = 0; k < scells; k++) {
+ ranges[i].size <<= 32;
+ ranges[i].size |= base_ranges[j++];
+ }
+
+ return ranges[i].host;
+ }
+ return -1;
+}
+
+uint64_t
+asmedia_fb_address(phandle_t node)
+{
+ while (node) {
+ if (OF_hasprop(node, "ranges")) {
+ uint64_t addr = parse_ranges(node);
+ node = OF_parent(node);
+ if (addr != 0)
+ return addr;
+ } else
+ node = OF_parent(node);
+ }
+
+ return 0;
+}
+
static void
ofwfb_initialize(struct vt_device *vd)
{
@@ -350,7 +438,7 @@
* There is no good way to determine the correct option, as this
* is independent of endian swapping.
*/
- if (sc->vendor_id == PCI_VENDOR_ID_NVIDIA)
+ if (sc->vendor_id == PCI_VID_NVIDIA)
sc->argb = 0;
else
sc->argb = 1;
@@ -430,7 +518,6 @@
sizeof(vendor_id)) == sizeof(vendor_id))
sc->vendor_id = vendor_id;
-
/* Keep track of the OF node */
sc->sc_node = node;
@@ -500,9 +587,11 @@
*/
user_phys = 0;
TUNABLE_UINT64_FETCH("hw.ofwfb.physaddr", &user_phys);
- fb_phys = (bus_addr_t)user_phys;
- if (fb_phys)
- sc->fb.fb_pbase = (vm_paddr_t)fb_phys;
+
+ if (user_phys) {
+ sc->fb.fb_pbase = (vm_paddr_t)user_phys;
+ } else if (sc->vendor_id == PCI_VID_ASPEED)
+ sc->fb.fb_pbase = (bus_addr_t)asmedia_fb_address(node);
else if (OF_hasprop(node, "address")) {
switch (OF_getproplen(node, "address")) {

File Metadata

Mime Type
text/plain
Expires
Thu, Jul 9, 7:01 PM (4 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29042947
Default Alt Text
D30626.1783623689.diff (3 KB)

Event Timeline