1 1.2 yamt /* $NetBSD: ioperm.c,v 1.2 2008/01/04 16:18:52 yamt Exp $ */ 2 1.1 yamt 3 1.1 yamt /*- 4 1.1 yamt * Copyright (c)2008 YAMAMOTO Takashi, 5 1.1 yamt * All rights reserved. 6 1.1 yamt * 7 1.1 yamt * Redistribution and use in source and binary forms, with or without 8 1.1 yamt * modification, are permitted provided that the following conditions 9 1.1 yamt * are met: 10 1.1 yamt * 1. Redistributions of source code must retain the above copyright 11 1.1 yamt * notice, this list of conditions and the following disclaimer. 12 1.1 yamt * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 yamt * notice, this list of conditions and the following disclaimer in the 14 1.1 yamt * documentation and/or other materials provided with the distribution. 15 1.1 yamt * 16 1.1 yamt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 1.1 yamt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 1.1 yamt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 1.1 yamt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 1.1 yamt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 1.1 yamt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 1.1 yamt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 1.1 yamt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 1.1 yamt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 yamt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 yamt * SUCH DAMAGE. 27 1.1 yamt */ 28 1.1 yamt 29 1.1 yamt #include <sys/cdefs.h> 30 1.1 yamt #ifndef lint 31 1.2 yamt __RCSID("$NetBSD: ioperm.c,v 1.2 2008/01/04 16:18:52 yamt Exp $"); 32 1.1 yamt #endif /* not lint */ 33 1.1 yamt 34 1.1 yamt #include <err.h> 35 1.1 yamt #include <signal.h> 36 1.1 yamt #include <setjmp.h> 37 1.1 yamt #include <stdbool.h> 38 1.1 yamt #include <stdint.h> 39 1.1 yamt #include <stdio.h> 40 1.1 yamt #include <stdlib.h> 41 1.1 yamt #include <string.h> 42 1.1 yamt #include <unistd.h> 43 1.1 yamt 44 1.1 yamt int i386_get_ioperm(unsigned long *); 45 1.1 yamt int i386_set_ioperm(unsigned long *); 46 1.1 yamt 47 1.1 yamt /* arbitrary port to test */ 48 1.1 yamt #define IO_TIMER1 0x40 49 1.1 yamt #define TIMER_CNTR0 0 50 1.1 yamt #define PORT (IO_TIMER1+TIMER_CNTR0) 51 1.1 yamt 52 1.1 yamt static uint8_t 53 1.1 yamt inb(uint16_t port) 54 1.1 yamt { 55 1.1 yamt uint8_t data; 56 1.1 yamt 57 1.1 yamt __asm __volatile("inb %1, %0" : "=a"(data) : "id"(port)); 58 1.1 yamt return data; 59 1.1 yamt } 60 1.1 yamt 61 1.1 yamt sigjmp_buf env; 62 1.1 yamt int gotsig; 63 1.1 yamt 64 1.1 yamt static void 65 1.1 yamt sighandler(int sig) 66 1.1 yamt { 67 1.1 yamt 68 1.1 yamt siglongjmp(env, sig); 69 1.1 yamt } 70 1.1 yamt 71 1.1 yamt static void 72 1.1 yamt try(const char *msg, bool success) 73 1.1 yamt { 74 1.1 yamt int sig; 75 1.1 yamt 76 1.1 yamt sig = sigsetjmp(env, 1); 77 1.1 yamt if (sig == 0) { 78 1.1 yamt inb(PORT); 79 1.1 yamt if (!success) { 80 1.1 yamt errx(EXIT_FAILURE, "%s: unexpected success of inb", 81 1.1 yamt msg); 82 1.1 yamt } 83 1.1 yamt return; 84 1.1 yamt } 85 1.1 yamt if (success) { 86 1.1 yamt errx(EXIT_FAILURE, "%s: got signal %d\n", msg, sig); 87 1.1 yamt } 88 1.1 yamt } 89 1.1 yamt 90 1.1 yamt int 91 1.1 yamt main(int argc, char *argv[]) 92 1.1 yamt { 93 1.1 yamt unsigned long buf[32]; 94 1.1 yamt unsigned long buf2[32]; 95 1.1 yamt int ret; 96 1.1 yamt int i; 97 1.1 yamt 98 1.1 yamt ret = i386_get_ioperm(buf); 99 1.1 yamt if (ret == -1) { 100 1.1 yamt err(EXIT_FAILURE, "get_ioperm 1"); 101 1.1 yamt } 102 1.1 yamt for (i = 0; i < __arraycount(buf); i++) { 103 1.1 yamt if (buf[i] != 0xffffffff) { 104 1.1 yamt errx(EXIT_FAILURE, "buf[%d] == 0x%lx", i, buf[i]); 105 1.1 yamt } 106 1.1 yamt } 107 1.1 yamt 108 1.1 yamt signal(SIGSEGV, sighandler); 109 1.1 yamt 110 1.1 yamt try("1", false); 111 1.2 yamt sleep(1); 112 1.1 yamt 113 1.1 yamt memset(buf2, 0x00, sizeof(buf2)); 114 1.1 yamt strcpy((char *)buf2, "foobarbaz"); 115 1.1 yamt buf2[PORT / 8 / sizeof(unsigned long)] &= 116 1.1 yamt ~(1 << (PORT % (8 * sizeof(unsigned long)))); 117 1.1 yamt ret = i386_set_ioperm(buf2); 118 1.1 yamt if (ret == -1) { 119 1.1 yamt err(EXIT_FAILURE, "set_ioperm 1"); 120 1.1 yamt } 121 1.1 yamt ret = i386_get_ioperm(buf); 122 1.1 yamt if (ret == -1) { 123 1.1 yamt err(EXIT_FAILURE, "get_ioperm 2"); 124 1.1 yamt } 125 1.1 yamt if (memcmp(buf, buf2, sizeof(buf))) { 126 1.1 yamt errx(EXIT_FAILURE, "iomap mismatch"); 127 1.1 yamt } 128 1.1 yamt 129 1.2 yamt sleep(1); 130 1.1 yamt try("2", true); 131 1.2 yamt sleep(1); 132 1.1 yamt 133 1.1 yamt buf2[PORT / 8 / sizeof(unsigned long)] |= 134 1.1 yamt (1 << (PORT % (8 * sizeof(unsigned long)))); 135 1.1 yamt ret = i386_set_ioperm(buf2); 136 1.1 yamt if (ret == -1) { 137 1.1 yamt err(EXIT_FAILURE, "set_ioperm 3"); 138 1.1 yamt } 139 1.1 yamt 140 1.2 yamt sleep(1); 141 1.1 yamt try("3", false); 142 1.1 yamt } 143