#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include "devopen.h" #include "dev/pci/sis1100_var.h" #include "dev/pci/sis5100_map.h" typedef int (*camacproc)(struct devinfo* dev, u_int32_t N, u_int32_t A, u_int32_t F, u_int32_t* data); #define CAMAC(base, N, A, F) \ ((base)+(((F)<<9)|((N)<<4)|(A))) static int camac_mapped(struct devinfo* dev, u_int32_t N, u_int32_t A, u_int32_t F, u_int32_t* data) { volatile u_int32_t* camaddr=CAMAC(dev->base_remote, N, A, F); if ((F&0x18)==0x10) { u_int32_t err; *camaddr=*data; err=*(dev->base_ctrl+0x2B); *data=(~err<<24)&0xc0000000; if (err && !(err&0xc0)) { printf("camac_mapped: err=0x%x\n", err); return -1; } } else { /* read or control */ *data=*camaddr^0xc0000000; } return 0; } static int camac_mapped_w(struct devinfo* dev, u_int32_t N, u_int32_t A, u_int32_t F, u_int32_t* data) { volatile u_int32_t* camaddr=CAMAC(dev->base_remote, N, A, F); u_int32_t err; *camaddr=*data; err=*(dev->base_ctrl+0x2B); *data=(~err<<24)&0xc0000000; if (err && !(err&0xc0)) { printf("camac_mapped: err=0x%x\n", err); return -1; } return 0; } static int camac_mapped_r(struct devinfo* dev, u_int32_t N, u_int32_t A, u_int32_t F, u_int32_t* data) { *data=(*CAMAC(dev->base_remote, N, A, F))^0xc0000000; return 0; } static int camac_driver_vme(struct devinfo* dev, u_int32_t N, u_int32_t A, u_int32_t F, u_int32_t* data) { struct sis1100_vme_req req; unsigned int camac_addr; int res; camac_addr=((F&0x1f)<<11)+((N&0x1f)<<6)+((A&0xf)<<2); req.size=4; req.am=-1; req.addr=camac_addr; req.data=*data; req.error=0; if ((F&0x18)==0x10) { res=ioctl(dev->p_remote, SIS3100_VME_WRITE, &req); *data=(~req.error<<24)&0xc0000000; } else { res=ioctl(dev->p_remote, SIS3100_VME_READ, &req); *data=req.data^0xc0000000; } if (res) { printf("driver_vme: res=%d\n", res); return -1; } if (req.error&~0x2c0) { printf("driver_vme: error=0x%x\n", req.error); return -1; } return 0; } static __inline int camac_driver(struct devinfo* dev, u_int32_t N, u_int32_t A, u_int32_t F, u_int32_t* data) { struct sis1100_camac_req req; int res; req.N=N; req.A=A; req.F=F; req.data=*data; req.error=0; res=ioctl(dev->p_remote, SIS5100_CNAF, &req); if (res) { printf("driver_camac: res=%d\n", res); return -1; } if (req.error) { printf("driver_camac: error=0x%x\n", req.error); return -1; } *data=req.data; return 0; } #if 0 static void test_inhibit(int p) { struct sis1100_ctrl_reg reg; while (1) { reg.offset=0x100; reg.val=0xffff; reg.error=0; if (ioctl(p, SIS1100_CTRL_WRITE, ®)<0) { fprintf(stderr, "ioctl(SIS1100_CTRL_WRITE, 0x100): %s\n", strerror(errno)); return; } if (reg.error!=0) { fprintf(stderr, "ioctl(SIS1100_CTRL_WRITE, 0x100): error=0x%x\n", reg.error); return; } sleep(1); reg.offset=0x100; reg.val=0xffff0000; reg.error=0; if (ioctl(p, SIS1100_CTRL_WRITE, ®)<0) { fprintf(stderr, "ioctl(SIS1100_CTRL_WRITE, 0x100): %s\n", strerror(errno)); return; } if (reg.error!=0) { fprintf(stderr, "ioctl(SIS1100_CTRL_WRITE, 0x100): error=0x%x\n", reg.error); return; } sleep(1); } } #else static void test_inhibit(int p) { int d=1; while (1) { if (ioctl(p, SIS5100_CCCI, &d)<0) { fprintf(stderr, "ioctl(SIS5100_CCCI, %d): %s\n", d, strerror(errno)); return; } d=1-d; sleep(1); } } #endif static int camac_count_driver_vme(struct devinfo* dev, int num) { struct sis1100_vme_req req; unsigned int camac_addr; int N=20; int A=0; int F=16; int p; p=dev->p_ctrl; if (p<0) p=dev->p_remote; if (p<0) return -1; camac_addr=((F&0x1f)<<11)+((N&0x1f)<<6)+((A&0xf)<<2); req.size=4; req.am=-1; req.addr=camac_addr; for (; num; num--) { int res; req.data=num; res=ioctl(p, SIS3100_VME_WRITE, &req); if (res) { printf("camac_write: res=%d\n", res); return -1; } if (req.error&0x3f) { printf("camac_write: error=0x%x\n", req.error); return -1; } } return 0; } static int camac_count_driver_camac(struct devinfo* dev, int num) { struct sis1100_camac_req req; int p; p=dev->p_ctrl; if (p<0) p=dev->p_remote; if (p<0) return -1; req.N=20; req.A=0; req.F=16; for (; num; num--) { int res; req.data=num; res=ioctl(p, SIS5100_CNAF, &req); if (res) { printf("camac_write: res=%d\n", res); return -1; } if (req.error) { printf("camac_write: error=0x%x\n", req.error); return -1; } } return 0; } static int camac_count_mapped(struct devinfo* dev, int num) { int F=16; int N=20; int A=0; volatile u_int32_t *addr; if (!dev->base_remote) return -1; addr=CAMAC(dev->base_remote, N, A, F); for (; num; num--) { *addr=num; } return 0; } typedef int (*countproc)(struct devinfo* dev, int num); static void camac_count(struct devinfo* dev, countproc proc, const char* text, int num) { struct timeval tv0, tv1; float tdiff, tcycle; int res; gettimeofday(&tv0, 0); res=proc(dev, num); gettimeofday(&tv1, 0); if (res) return; tdiff=tv1.tv_sec-tv0.tv_sec; tdiff+=(tv1.tv_usec-tv0.tv_usec)/1000000.; tcycle=(tdiff*1000000.)/num; printf("%s: %f us\n", text, tcycle); } static void fill_4302(struct devinfo* dev, camacproc proc, const char* text, int N, int num) { u_int32_t d, i, x; struct timeval tv0, tv1; float tdiff, tcycle; d=1; proc(dev, N, 1, 17, &d); /* set MODE to CAMAC */ camac_mapped(dev, N, 1, 1, &d); printf("mode: %x\n", d&3); gettimeofday(&tv0, 0); for (x=100; x; x--) { d=0; proc(dev, N, 0, 17, &d); /* set ADDR */ for (i=0; ibase_remote; err=*(dev->base_ctrl+0x2B); d=*(dev->base_ctrl+0x2A); printf("(b) initial err: 0x%x, balance=%d\n", err, d); *CAMAC(base, N, 1, 17)=1; /* set MODE to CAMAC */ err=*(dev->base_ctrl+0x2B); d=*(dev->base_ctrl+0x2A); printf("(set mode) err: 0x%x, balance=%d\n", err, d); /* read mode */ d=*CAMAC(base, N, 1, 1); printf("mode: %x\n", d&3); err=*(dev->base_ctrl+0x2B); d=*(dev->base_ctrl+0x2A); printf("(read mode) err: 0x%x, balance=%d\n", err, d); gettimeofday(&tv0, 0); for (x=100; x; x--) { addr=CAMAC(base, N, 0, 17); *addr=0; /* set ADDR */ err=*(dev->base_ctrl+0x2B); if (err) { d=*(dev->base_ctrl+0x2A); printf("(set addr) err: 0x%x, balance=%d\n", err, d); goto raus; } addr=CAMAC(base, N, 0, 16); for (i=0; ibase_ctrl+0x2B);*/ /* * if (err&0xc0) { * printf("fill_4302_mapped: QX: 0x%x\n", err); * goto raus; * } */ } do { err=*(dev->base_ctrl+0x2B); d=*(dev->base_ctrl+0x2A); } while (err==0x107); if (err) { printf("(after write) err: 0x%x, balance=%d\n", err, d); goto raus; } } raus: gettimeofday(&tv1, 0); addr=CAMAC(base, N, 0, 1); d=*addr; printf("addr after write: 0x%x; i=%d\n", d, i); tdiff=tv1.tv_sec-tv0.tv_sec; tdiff+=(tv1.tv_usec-tv0.tv_usec)/1000000.; tcycle=(tdiff*1000000.)/i/100.; printf("%s: %f us\n", text, tcycle); } static void read_4302(struct devinfo* dev, camacproc proc, const char* text, int N, int num) { struct timeval tv0, tv1; float tdiff, tcycle; u_int32_t d, i=0, x; gettimeofday(&tv0, 0); for (x=100; x; x--) { d=0; camac_mapped(dev, N, 0, 17, &d); /* set ADDR */ for (i=0; ibase_remote; addr=CAMAC((u_int32_t*)0, N, 0, 17); /* set ADDR */ printf("offset=%p\n", addr); gettimeofday(&tv0, 0); for (x=1; x; x--) { addr=CAMAC(base, N, 0, 17); /* set ADDR */ *addr=0; err=*(dev->base_ctrl+0x2B); if (err) { d=*(dev->base_ctrl+0x2A); printf("(set addr) err: 0x%x, balance=%d\n", err, d); goto raus; } addr=CAMAC(base, N, 0, 0); /* read data */ for (i=0; i=0) { test_inhibit(devinfo.p_ctrl); } else { printf("remote path not open.\n"); } #endif #if 0 camac_count(&devinfo, camac_count_driver_vme, "vme ", 1000000); camac_count(&devinfo, camac_count_driver_camac, "camac ", 1000000); camac_count(&devinfo, camac_count_mapped, "mapped", 1000000); #endif #if 0 { int p; p=devinfo.p_ctrl; if (p<0) p=devinfo.p_remote; if (p>=0) { camac_count_driver_vme(p); } else { printf("neither ctrl nor remote device open.\n"); } } { int p; p=devinfo.p_ctrl; if (p<0) p=devinfo.p_remote; if (p>=0) { camac_count_driver_camac(p); } else { printf("neither ctrl nor remote device open.\n"); } } { if (devinfo.base_remote!=MAP_FAILED) { camac_count_mapped(devinfo); } else { printf("CAMAC space not mapped.\n"); } } #endif #if 0 fill_4302(&devinfo, camac_driver_vme, "vme", 21, 16384); read_4302(&devinfo, camac_driver_vme, "vme", 21, 16384); fill_4302(&devinfo, camac_driver, "camac", 21, 16384); read_4302(&devinfo, camac_driver, "camac", 21, 16384); fill_4302_mapped(&devinfo, "fill_mapped_m", 21, 1000); fill_4302(&devinfo, camac_mapped_w, "fill_mapped_w", 21, 1000); read_4302(&devinfo, camac_mapped_r, "read_mapped_r", 21, 1000); read_4302(&devinfo, camac_mapped, "read_mapped", 21, 1000); #endif read_4302_mapped(&devinfo, "read_mapped_m", 21, 1000); return 0; }