From owner-freebsd-bugs Thu Nov 29 23:47:14 2001 Delivered-To: freebsd-bugs@freebsd.org Received: from staff.rinet.ru (staff.rinet.ru [195.54.192.46]) by hub.freebsd.org (Postfix) with ESMTP id 3070137B405; Thu, 29 Nov 2001 23:47:04 -0800 (PST) Received: from localhost (gvs@localhost [127.0.0.1]) by staff.rinet.ru (8.11.6/8.11.4) with ESMTP id fAU7l1t12176; Fri, 30 Nov 2001 10:47:02 +0300 (MSK) (envelope-from gvs@rinet.ru) Date: Fri, 30 Nov 2001 10:47:01 +0300 (MSK) From: Seva Gluschenko X-X-Sender: gvs@localhost To: murray@FreeBSD.org Cc: freebsd-bugs@FreeBSD.org, Joe Orthoefer Subject: Re: kern/32255: AMD761(tm) and MGA G550 are not known by PCI kernel routines In-Reply-To: <200111282042.fASKgga10046@freefall.freebsd.org> Message-ID: <20011129163953.S43189-100000@localhost> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org 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 (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