Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147504748
D30626.1783623689.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D30626.1783623689.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D30626: ofwfb: fix vga/hdmi console during boot on powerpc64
Attached
Detach File
Event Timeline
Log In to Comment