1 //
2 // Copyright(C) 2005-2014 Simon Howard
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // DESCRIPTION:
15 //     OPL OpenBSD interface (also NetBSD)
16 //
17 
18 #include "config.h"
19 
20 // OpenBSD has a i386_iopl on i386 and amd64_iopl on x86_64,
21 // even though they do the same thing.  Take care of this
22 // here, and map set_iopl to point to the appropriate name.
23 
24 #if defined(HAVE_LIBI386)
25 
26 #include <sys/types.h>
27 #include <machine/sysarch.h>
28 #include <i386/pio.h>
29 #define set_iopl i386_iopl
30 
31 #elif defined(HAVE_LIBAMD64)
32 
33 #include <sys/types.h>
34 #include <machine/sysarch.h>
35 #include <amd64/pio.h>
36 #define set_iopl amd64_iopl
37 
38 #else
39 #define NO_OBSD_DRIVER
40 #endif
41 
42 // If the above succeeded, proceed with the rest.
43 
44 #ifndef NO_OBSD_DRIVER
45 
46 #include <stdio.h>
47 #include <string.h>
48 #include <errno.h>
49 #include <unistd.h>
50 
51 #include "opl.h"
52 #include "opl_internal.h"
53 #include "opl_timer.h"
54 
55 static unsigned int opl_port_base;
56 
OPL_OpenBSD_Init(unsigned int port_base)57 static int OPL_OpenBSD_Init(unsigned int port_base)
58 {
59     // Try to get permissions:
60 
61     if (set_iopl(3) < 0)
62     {
63         fprintf(stderr, "Failed to get raise I/O privilege level: "
64                         "check that you are running as root.\n");
65         return 0;
66     }
67 
68     opl_port_base = port_base;
69 
70     // Start callback thread
71 
72     if (!OPL_Timer_StartThread())
73     {
74         set_iopl(0);
75         return 0;
76     }
77 
78     return 1;
79 }
80 
OPL_OpenBSD_Shutdown(void)81 static void OPL_OpenBSD_Shutdown(void)
82 {
83     // Stop callback thread
84 
85     OPL_Timer_StopThread();
86 
87     // Release I/O port permissions:
88 
89     set_iopl(0);
90 }
91 
OPL_OpenBSD_PortRead(opl_port_t port)92 static unsigned int OPL_OpenBSD_PortRead(opl_port_t port)
93 {
94     return inb(opl_port_base + port);
95 }
96 
OPL_OpenBSD_PortWrite(opl_port_t port,unsigned int value)97 static void OPL_OpenBSD_PortWrite(opl_port_t port, unsigned int value)
98 {
99     outb(opl_port_base + port, value);
100 }
101 
102 opl_driver_t opl_openbsd_driver =
103 {
104     "OpenBSD",
105     OPL_OpenBSD_Init,
106     OPL_OpenBSD_Shutdown,
107     OPL_OpenBSD_PortRead,
108     OPL_OpenBSD_PortWrite,
109     OPL_Timer_SetCallback,
110     OPL_Timer_ClearCallbacks,
111     OPL_Timer_Lock,
112     OPL_Timer_Unlock,
113     OPL_Timer_SetPaused,
114     OPL_Timer_AdjustCallbacks,
115 };
116 
117 #endif /* #ifndef NO_OBSD_DRIVER */
118 
119