diff options
author | marcel <marcel@FreeBSD.org> | 2007-06-09 21:55:17 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2007-06-09 21:55:17 +0000 |
commit | 75588c5a15dad18e2f69aee6a984065d314bffb7 (patch) | |
tree | a56b45624c5012a67b32e122f42c41c6b2e7d8a4 | |
parent | 12d804e413f2c44d9e10f25ee1b546f2b48c598b (diff) | |
download | FreeBSD-src-75588c5a15dad18e2f69aee6a984065d314bffb7.zip FreeBSD-src-75588c5a15dad18e2f69aee6a984065d314bffb7.tar.gz |
Add kdb_cpu_sync_icache(), intended to synchronize instruction
caches with data caches after writing to memory. This typically
is required to make breakpoints work on ia64 and powerpc. For
those architectures the function is implemented.
-rw-r--r-- | sys/amd64/include/kdb.h | 5 | ||||
-rw-r--r-- | sys/arm/include/kdb.h | 5 | ||||
-rw-r--r-- | sys/gdb/gdb_packet.c | 10 | ||||
-rw-r--r-- | sys/i386/include/kdb.h | 5 | ||||
-rw-r--r-- | sys/ia64/include/kdb.h | 15 | ||||
-rw-r--r-- | sys/powerpc/aim/uio_machdep.c | 2 | ||||
-rw-r--r-- | sys/powerpc/include/cpu.h | 6 | ||||
-rw-r--r-- | sys/powerpc/include/kdb.h | 7 | ||||
-rw-r--r-- | sys/powerpc/include/md_var.h | 6 | ||||
-rw-r--r-- | sys/powerpc/powerpc/db_interface.c | 16 | ||||
-rw-r--r-- | sys/powerpc/powerpc/syncicache.c | 2 | ||||
-rw-r--r-- | sys/powerpc/powerpc/uio_machdep.c | 2 | ||||
-rw-r--r-- | sys/sparc64/include/kdb.h | 5 | ||||
-rw-r--r-- | sys/sun4v/include/kdb.h | 5 |
14 files changed, 70 insertions, 21 deletions
diff --git a/sys/amd64/include/kdb.h b/sys/amd64/include/kdb.h index 131e40e..56d2018 100644 --- a/sys/amd64/include/kdb.h +++ b/sys/amd64/include/kdb.h @@ -47,6 +47,11 @@ kdb_cpu_set_singlestep(void) } static __inline void +kdb_cpu_sync_icache(unsigned char *addr, size_t size) +{ +} + +static __inline void kdb_cpu_trap(int type, int code) { } diff --git a/sys/arm/include/kdb.h b/sys/arm/include/kdb.h index 9d933d6..7452922 100644 --- a/sys/arm/include/kdb.h +++ b/sys/arm/include/kdb.h @@ -44,6 +44,11 @@ kdb_cpu_set_singlestep(void) } static __inline void +kdb_cpu_sync_icache(unsigned char *addr, size_t size) +{ +} + +static __inline void kdb_cpu_trap(int type, int code) { cpu_idcache_wbinv_all(); diff --git a/sys/gdb/gdb_packet.c b/sys/gdb/gdb_packet.c index 753c9b7..d3e5a0a 100644 --- a/sys/gdb/gdb_packet.c +++ b/sys/gdb/gdb_packet.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kdb.h> #include <machine/gdb_machdep.h> +#include <machine/kdb.h> #include <gdb/gdb.h> #include <gdb/gdb_int.h> @@ -129,8 +130,10 @@ gdb_rx_equal(const char *str) int gdb_rx_mem(unsigned char *addr, size_t size) { + unsigned char *p; void *prev; jmp_buf jb; + size_t cnt; int ret; unsigned char c; @@ -140,13 +143,16 @@ gdb_rx_mem(unsigned char *addr, size_t size) prev = kdb_jmpbuf(jb); ret = setjmp(jb); if (ret == 0) { - while (size-- > 0) { + p = addr; + cnt = size; + while (cnt-- > 0) { c = (C2N(gdb_rxp[0]) << 4) & 0xf0; c |= C2N(gdb_rxp[1]) & 0x0f; - *addr++ = c; + *p++ = c; gdb_rxsz -= 2; gdb_rxp += 2; } + kdb_cpu_sync_icache(addr, size); } (void)kdb_jmpbuf(prev); return ((ret == 0) ? 1 : 0); diff --git a/sys/i386/include/kdb.h b/sys/i386/include/kdb.h index 77e1a6b..1b407cb 100644 --- a/sys/i386/include/kdb.h +++ b/sys/i386/include/kdb.h @@ -47,6 +47,11 @@ kdb_cpu_set_singlestep(void) } static __inline void +kdb_cpu_sync_icache(unsigned char *addr, size_t size) +{ +} + +static __inline void kdb_cpu_trap(int type, int code) { } diff --git a/sys/ia64/include/kdb.h b/sys/ia64/include/kdb.h index 57d84bc..d8a12e0 100644 --- a/sys/ia64/include/kdb.h +++ b/sys/ia64/include/kdb.h @@ -48,6 +48,21 @@ kdb_cpu_set_singlestep(void) } static __inline void +kdb_cpu_sync_icache(unsigned char *addr, size_t size) +{ + vm_offset_t cacheline; + + cacheline = (uintptr_t)addr & ~31; + size += (uintptr_t)addr - cacheline; + size = (size + 31) & ~31; + while (size > 0) { + __asm __volatile("fc %0;; sync.i;; srlz.i;;" :: "r"(cacheline)); + cacheline += 32; + size -= 32; + } +} + +static __inline void kdb_cpu_trap(int vector, int _) { __asm __volatile("flushrs;;"); diff --git a/sys/powerpc/aim/uio_machdep.c b/sys/powerpc/aim/uio_machdep.c index a52f729..070ad98 100644 --- a/sys/powerpc/aim/uio_machdep.c +++ b/sys/powerpc/aim/uio_machdep.c @@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm.h> #include <vm/vm_page.h> -#include <machine/cpu.h> +#include <machine/md_var.h> #include <machine/vmparam.h> /* diff --git a/sys/powerpc/include/cpu.h b/sys/powerpc/include/cpu.h index dc7ae3d..a8fea27 100644 --- a/sys/powerpc/include/cpu.h +++ b/sys/powerpc/include/cpu.h @@ -45,12 +45,6 @@ #define cpu_swapout(p) #define cpu_number() 0 -#if defined(_KERNEL) || defined(_STANDALONE) -#define CACHELINESIZE 32 -#endif - -extern void __syncicache(void *, int); - /* * CTL_MACHDEP definitions. */ diff --git a/sys/powerpc/include/kdb.h b/sys/powerpc/include/kdb.h index 2cfc063..2cb49a8 100644 --- a/sys/powerpc/include/kdb.h +++ b/sys/powerpc/include/kdb.h @@ -31,6 +31,7 @@ #include <machine/cpufunc.h> #include <machine/frame.h> +#include <machine/md_var.h> #include <machine/psl.h> static __inline void @@ -46,6 +47,12 @@ kdb_cpu_set_singlestep(void) } static __inline void +kdb_cpu_sync_icache(unsigned char *addr, size_t size) +{ + __syncicache(addr, size); +} + +static __inline void kdb_cpu_trap(int vector, int _) { } diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h index fa868c1..7248e4b 100644 --- a/sys/powerpc/include/md_var.h +++ b/sys/powerpc/include/md_var.h @@ -50,6 +50,12 @@ struct reg; struct cam_sim; struct pcicfg; +#if defined(_KERNEL) || defined(_STANDALONE) +#define CACHELINESIZE 32 +#endif + +void __syncicache(void *, int); + void busdma_swi(void); int is_physical_memory(vm_offset_t addr); int mem_valid(vm_offset_t addr, int len); diff --git a/sys/powerpc/powerpc/db_interface.c b/sys/powerpc/powerpc/db_interface.c index a46ead6..3dae648 100644 --- a/sys/powerpc/powerpc/db_interface.c +++ b/sys/powerpc/powerpc/db_interface.c @@ -13,7 +13,7 @@ #include <sys/proc.h> #include <sys/smp.h> -#include <machine/cpu.h> +#include <machine/kdb.h> #include <machine/md_var.h> #include <vm/vm.h> @@ -58,23 +58,19 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data) jmp_buf jb; void *prev_jb; char *dst; + size_t cnt; int ret; prev_jb = kdb_jmpbuf(jb); ret = setjmp(jb); if (ret == 0) { dst = (char *)addr; + cnt = size; - if (size == 4) - *((int *)dst) = *((int *)data); - else if (size == 2) - *((short *)dst) = *((short *)data); - else - while (size-- > 0) - *dst++ = *data++; + while (cnt-- > 0) + *dst++ = *data++; + kdb_cpu_sync_icache((void *)addr, size); } - __syncicache((void *)addr, size); - (void)kdb_jmpbuf(prev_jb); return (ret); } diff --git a/sys/powerpc/powerpc/syncicache.c b/sys/powerpc/powerpc/syncicache.c index 9a5b8c6..3d4f732 100644 --- a/sys/powerpc/powerpc/syncicache.c +++ b/sys/powerpc/powerpc/syncicache.c @@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$"); #endif #include <sys/sysctl.h> -#include <machine/cpu.h> +#include <machine/md_var.h> #if defined(_KERNEL) || defined(_STANDALONE) #ifndef CACHELINESIZE diff --git a/sys/powerpc/powerpc/uio_machdep.c b/sys/powerpc/powerpc/uio_machdep.c index a52f729..070ad98 100644 --- a/sys/powerpc/powerpc/uio_machdep.c +++ b/sys/powerpc/powerpc/uio_machdep.c @@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm.h> #include <vm/vm_page.h> -#include <machine/cpu.h> +#include <machine/md_var.h> #include <machine/vmparam.h> /* diff --git a/sys/sparc64/include/kdb.h b/sys/sparc64/include/kdb.h index 3e510e0..02ce4e7 100644 --- a/sys/sparc64/include/kdb.h +++ b/sys/sparc64/include/kdb.h @@ -44,6 +44,11 @@ kdb_cpu_set_singlestep(void) } static __inline void +kdb_cpu_sync_icache(unsigned char *addr, size_t size) +{ +} + +static __inline void kdb_cpu_trap(int vector, int _) { flushw(); diff --git a/sys/sun4v/include/kdb.h b/sys/sun4v/include/kdb.h index e5b39c0..92b2ed7 100644 --- a/sys/sun4v/include/kdb.h +++ b/sys/sun4v/include/kdb.h @@ -42,6 +42,11 @@ kdb_cpu_set_singlestep(void) } static __inline void +kdb_cpu_sync_icache(unsigned char *addr, size_t size) +{ +} + +static __inline void kdb_cpu_trap(int vector, int _) { flushw(); |