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