mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-01 08:33:24 +00:00
Add cpu_flush_dcache() for use after non-DMA based I/O so that a
possible future I-cache coherency operation can succeed. On ARM for example the L1 cache can be (is) virtually mapped, which means that any I/O that uses temporary mappings will not see the I-cache made coherent. On ia64 a similar behaviour has been observed. By flushing the D-cache, execution of binaries backed by md(4) and/or NFS work reliably. For Book-E (powerpc), execution over NFS exhibits SIGILL once in a while as well, though cpu_flush_dcache() hasn't been implemented yet. Doing an explicit D-cache flush as part of the non-DMA based I/O read operation eliminates the need to do it as part of the I-cache coherency operation itself and as such avoids pessimizing the DMA-based I/O read operations for which D-cache are already flushed/invalidated. It also allows future optimizations whereby the bcopy() followed by the D-cache flush can be integrated in a single operation, which could be implemented using on-chips DMA engines, by-passing the D-cache altogether.
This commit is contained in:
parent
e13e5f8fa5
commit
dbb95048da
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=192323
@ -506,6 +506,16 @@ cpu_boot(int howto)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the D-cache for non-DMA I/O so that the I-cache can
|
||||
* be made coherent later.
|
||||
*/
|
||||
void
|
||||
cpu_flush_dcache(void *ptr, size_t len)
|
||||
{
|
||||
/* Not applicable */
|
||||
}
|
||||
|
||||
/* Get current clock frequency for the given cpu id. */
|
||||
int
|
||||
cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
|
@ -316,6 +316,18 @@ cpu_startup(void *dummy)
|
||||
|
||||
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
|
||||
|
||||
/*
|
||||
* Flush the D-cache for non-DMA I/O so that the I-cache can
|
||||
* be made coherent later.
|
||||
*/
|
||||
void
|
||||
cpu_flush_dcache(void *ptr, size_t len)
|
||||
{
|
||||
|
||||
cpu_dcache_wb_range((uintptr_t)ptr, len);
|
||||
cpu_l2cache_wb_range((uintptr_t)ptr, len);
|
||||
}
|
||||
|
||||
/* Get current clock frequency for the given cpu id. */
|
||||
int
|
||||
cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
|
@ -436,10 +436,11 @@ mdstart_malloc(struct md_s *sc, struct bio *bp)
|
||||
if (osp == 0)
|
||||
bzero(dst, sc->sectorsize);
|
||||
else if (osp <= 255)
|
||||
for (i = 0; i < sc->sectorsize; i++)
|
||||
dst[i] = osp;
|
||||
else
|
||||
memset(dst, osp, sc->sectorsize);
|
||||
else {
|
||||
bcopy((void *)osp, dst, sc->sectorsize);
|
||||
cpu_flush_dcache(dst, sc->sectorsize);
|
||||
}
|
||||
osp = 0;
|
||||
} else if (bp->bio_cmd == BIO_WRITE) {
|
||||
if (sc->flags & MD_COMPRESS) {
|
||||
@ -491,6 +492,7 @@ mdstart_preload(struct md_s *sc, struct bio *bp)
|
||||
case BIO_READ:
|
||||
bcopy(sc->pl_ptr + bp->bio_offset, bp->bio_data,
|
||||
bp->bio_length);
|
||||
cpu_flush_dcache(bp->bio_data, bp->bio_length);
|
||||
break;
|
||||
case BIO_WRITE:
|
||||
bcopy(bp->bio_data, sc->pl_ptr + bp->bio_offset,
|
||||
@ -633,6 +635,7 @@ mdstart_swap(struct md_s *sc, struct bio *bp)
|
||||
break;
|
||||
}
|
||||
bcopy((void *)(sf_buf_kva(sf) + offs), p, len);
|
||||
cpu_flush_dcache(p, len);
|
||||
} else if (bp->bio_cmd == BIO_WRITE) {
|
||||
if (len != PAGE_SIZE && m->valid != VM_PAGE_BITS_ALL)
|
||||
rv = vm_pager_get_pages(sc->object, &m, 1, 0);
|
||||
|
@ -1113,6 +1113,16 @@ cpu_boot(int howto)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the D-cache for non-DMA I/O so that the I-cache can
|
||||
* be made coherent later.
|
||||
*/
|
||||
void
|
||||
cpu_flush_dcache(void *ptr, size_t len)
|
||||
{
|
||||
/* Not applicable */
|
||||
}
|
||||
|
||||
/* Get current clock frequency for the given cpu id. */
|
||||
int
|
||||
cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
|
@ -311,6 +311,21 @@ cpu_boot(int howto)
|
||||
efi_reset_system();
|
||||
}
|
||||
|
||||
void
|
||||
cpu_flush_dcache(void *ptr, size_t len)
|
||||
{
|
||||
vm_offset_t lim, va;
|
||||
|
||||
va = (uintptr_t)ptr & ~31;
|
||||
lim = (uintptr_t)ptr + len;
|
||||
while (va < lim) {
|
||||
ia64_fc(va);
|
||||
va += 32;
|
||||
}
|
||||
|
||||
ia64_srlz_d();
|
||||
}
|
||||
|
||||
/* Get current clock frequency for the given cpu id. */
|
||||
int
|
||||
cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
|
@ -200,6 +200,16 @@ cpu_reset(void)
|
||||
platform_reset();
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the D-cache for non-DMA I/O so that the I-cache can
|
||||
* be made coherent later.
|
||||
*/
|
||||
void
|
||||
cpu_flush_dcache(void *ptr, size_t len)
|
||||
{
|
||||
/* TBD */
|
||||
}
|
||||
|
||||
/* Get current clock frequency for the given cpu id. */
|
||||
int
|
||||
cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
|
@ -127,9 +127,10 @@ nfsm_mbuftouio(struct mbuf **mrep, struct uio *uiop, int siz, caddr_t *dpos)
|
||||
(mbufcp, uiocp, xfer);
|
||||
else
|
||||
#endif
|
||||
if (uiop->uio_segflg == UIO_SYSSPACE)
|
||||
if (uiop->uio_segflg == UIO_SYSSPACE) {
|
||||
bcopy(mbufcp, uiocp, xfer);
|
||||
else
|
||||
cpu_flush_dcache(uiocp, xfer);
|
||||
} else
|
||||
copyout(mbufcp, uiocp, xfer);
|
||||
left -= xfer;
|
||||
len -= xfer;
|
||||
|
@ -1050,6 +1050,16 @@ cpu_boot(int howto)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the D-cache for non-DMA I/O so that the I-cache can
|
||||
* be made coherent later.
|
||||
*/
|
||||
void
|
||||
cpu_flush_dcache(void *ptr, size_t len)
|
||||
{
|
||||
/* Not applicable */
|
||||
}
|
||||
|
||||
/* Get current clock frequency for the given cpu id. */
|
||||
int
|
||||
cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
|
@ -864,6 +864,16 @@ cpu_boot(int howto)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the D-cache for non-DMA I/O so that the I-cache can
|
||||
* be made coherent later.
|
||||
*/
|
||||
void
|
||||
cpu_flush_dcache(void *ptr, size_t len)
|
||||
{
|
||||
/* TBD */
|
||||
}
|
||||
|
||||
void
|
||||
cpu_initclocks(void)
|
||||
{
|
||||
|
@ -556,6 +556,16 @@ fill_fpregs(struct thread *td, struct fpreg *fpregs)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the D-cache for non-DMA I/O so that the I-cache can
|
||||
* be made coherent later.
|
||||
*/
|
||||
void
|
||||
cpu_flush_dcache(void *ptr, size_t len)
|
||||
{
|
||||
/* TBD */
|
||||
}
|
||||
|
||||
/* Get current clock frequency for the given cpu id. */
|
||||
int
|
||||
cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
|
@ -742,6 +742,16 @@ cpu_shutdown(void *args)
|
||||
ofw_exit(args);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the D-cache for non-DMA I/O so that the I-cache can
|
||||
* be made coherent later.
|
||||
*/
|
||||
void
|
||||
cpu_flush_dcache(void *ptr, size_t len)
|
||||
{
|
||||
/* TBD */
|
||||
}
|
||||
|
||||
/* Get current clock frequency for the given CPU ID. */
|
||||
int
|
||||
cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
|
@ -767,6 +767,16 @@ cpu_shutdown(void *args)
|
||||
hv_mach_exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the D-cache for non-DMA I/O so that the I-cache can
|
||||
* be made coherent later.
|
||||
*/
|
||||
void
|
||||
cpu_flush_dcache(void *ptr, size_t len)
|
||||
{
|
||||
/* TBD */
|
||||
}
|
||||
|
||||
/* Get current clock frequency for the given cpu id. */
|
||||
int
|
||||
cpu_est_clockrate(int cpu_id, uint64_t *rate)
|
||||
|
@ -147,6 +147,7 @@ void panic(const char *, ...) __dead2 __printflike(1, 2);
|
||||
#endif
|
||||
|
||||
void cpu_boot(int);
|
||||
void cpu_flush_dcache(void *, size_t);
|
||||
void cpu_rootconf(void);
|
||||
void critical_enter(void);
|
||||
void critical_exit(void);
|
||||
|
Loading…
Reference in New Issue
Block a user