Date: Fri, 30 Nov 2001 10:47:01 +0300 (MSK) From: Seva Gluschenko <gvs@rinet.ru> To: murray@FreeBSD.org Cc: freebsd-bugs@FreeBSD.org, Joe Orthoefer <joeo@nks.net> Subject: Re: kern/32255: AMD761(tm) and MGA G550 are not known by PCI kernel routines Message-ID: <20011129163953.S43189-100000@localhost> In-Reply-To: <200111282042.fASKgga10046@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Message of murray@FreeBSD.org at Nov 28 12:42 ... > I'll update the patch and commit this to -CURRENT soon. > > http://www.FreeBSD.org/cgi/query-pr.cgi?pr=32255 Please, take into consideration also the following PR: http://www.FreeBSD.org/cgi/query-pr.cgi?pr=i386/32301 which has been originally submitted by Joe Orthoefer <joeo@nks.net> (to whom I cc: this message). His patch based on 4.4-RELEASE. I revised it and re-applied with some handwork for -stable, so it should look like follows. It mixes with my patch in one hunk (at agp_amd.c) - you may safely omit my own because this one supercedes it. *** agp_amd.c.orig Thu Nov 29 14:21:02 2001 --- agp_amd.c Thu Nov 29 14:20:43 2001 *************** *** 61,66 **** --- 61,67 ---- u_int32_t *ag_vdir; /* virtual address of page dir */ vm_offset_t ag_pdir; /* physical address of page dir */ u_int32_t *ag_virtual; /* virtual address of gatt */ + vm_offset_t ag_physical; /* physical address of the gatt */ }; struct agp_amd_softc { *************** *** 78,84 **** u_int32_t apsize = AGP_GET_APERTURE(dev); u_int32_t entries = apsize >> AGP_PAGE_SHIFT; struct agp_amd_gatt *gatt; ! int i, npages; if (bootverbose) device_printf(dev, --- 79,85 ---- u_int32_t apsize = AGP_GET_APERTURE(dev); u_int32_t entries = apsize >> AGP_PAGE_SHIFT; struct agp_amd_gatt *gatt; ! int i, npages, pdir_offset; if (bootverbose) device_printf(dev, *************** *** 92,109 **** /* * The AMD751 uses a page directory to map a non-contiguous * gatt so we don't need to use contigmalloc. */ - gatt->ag_entries = entries; - gatt->ag_virtual = malloc(entries * sizeof(u_int32_t), - M_AGP, M_NOWAIT); - if (!gatt->ag_virtual) { - if (bootverbose) - device_printf(dev, "allocation failed\n"); - free(gatt, M_AGP); - return 0; - } - bzero(gatt->ag_virtual, entries * sizeof(u_int32_t)); - /* * Allocate the page directory. */ --- 93,101 ---- /* * The AMD751 uses a page directory to map a non-contiguous * gatt so we don't need to use contigmalloc. + * Malloc indiviual gatt pages and map them into the page + * directory. */ /* * Allocate the page directory. */ *************** *** 118,128 **** } bzero(gatt->ag_vdir, AGP_PAGE_SIZE); gatt->ag_pdir = vtophys((vm_offset_t) gatt->ag_vdir); ! gatt->ag_pdir = vtophys(gatt->ag_virtual); /* * Map the pages of the GATT into the page directory. */ npages = ((entries * sizeof(u_int32_t) + AGP_PAGE_SIZE - 1) >> AGP_PAGE_SHIFT); for (i = 0; i < npages; i++) { --- 110,150 ---- } bzero(gatt->ag_vdir, AGP_PAGE_SIZE); gatt->ag_pdir = vtophys((vm_offset_t) gatt->ag_vdir); ! ! if (bootverbose) ! device_printf(dev, "gatt -> ag_pdir %8x\n", ! (vm_offset_t) gatt->ag_pdir ); ! /* ! * Allocate the gatt pages ! */ ! ! if (bootverbose) ! device_printf(dev, ! "allocating GATT for %d AGP page entries\n", ! entries); ! gatt->ag_entries = entries; ! gatt->ag_virtual = malloc(entries * sizeof(u_int32_t), ! M_AGP, M_NOWAIT); ! if (!gatt->ag_virtual) { ! if (bootverbose) ! device_printf(dev, "allocation failed\n"); ! free(gatt, M_AGP); ! return 0; ! } ! bzero(gatt->ag_virtual, entries * sizeof(u_int32_t)); ! gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual); /* * Map the pages of the GATT into the page directory. + * + * The gatt page addresses are mapped into the directory + * offset by an amount dependent on the base address of the + * aperture. This is an offset into the page directory + * not an offset added to the addresses of the gatt pages. */ + + pdir_offset = pci_read_config(dev, AGP_APBASE, 4) >> 22; + npages = ((entries * sizeof(u_int32_t) + AGP_PAGE_SIZE - 1) >> AGP_PAGE_SHIFT); for (i = 0; i < npages; i++) { *************** *** 131,137 **** va = ((vm_offset_t) gatt->ag_virtual) + i * AGP_PAGE_SIZE; pa = vtophys(va); ! gatt->ag_vdir[i] = pa | 1; } /* --- 153,159 ---- va = ((vm_offset_t) gatt->ag_virtual) + i * AGP_PAGE_SIZE; pa = vtophys(va); ! gatt->ag_vdir[i + pdir_offset] = pa | 1; } /* *************** *** 163,168 **** --- 185,194 ---- switch (pci_get_devid(dev)) { case 0x70061022: return ("AMD 751 host to AGP bridge"); + case 0x700e1022: + return ("AMD 761 host to AGP bridge"); + case 0x700c1022: + return ("AMD 762 host to AGP bridge"); }; return NULL; *************** *** 301,309 **** vas = ffs(aperture / 32*1024*1024) - 1; pci_write_config(dev, AGP_AMD751_APCTRL, ! ((pci_read_config(dev, AGP_AMD751_APCTRL, 1) & ~0x06) ! | vas << 1), 1); return 0; } --- 327,340 ---- vas = ffs(aperture / 32*1024*1024) - 1; + /* + * while the size register is bits 1-3 of APCTRL, bit 0 needs + * be set for the size value to be "valid" + */ + pci_write_config(dev, AGP_AMD751_APCTRL, ! (((pci_read_config(dev, AGP_AMD751_APCTRL, 1) & ~0x06) ! | ((vas << 1) | 1))), 1); return 0; } *************** *** 317,322 **** --- 348,357 ---- return EINVAL; sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 1; + + /* ivalidate the cache */ + AGP_FLUSH_TLB(dev); + return 0; } SY, Seva Gluschenko, just stranger on The Road. | http://gvs.rinet.ru/ Cronyx Plus / RiNet network administrator. | GVS-RIPE | GVS3-RIPN To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011129163953.S43189-100000>