summaryrefslogtreecommitdiff
path: root/util/dell-flash-unlock/accessors.c
blob: 0a5df760a308525d3e583ca2bc1c4910ac6a82e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* SPDX-License-Identifier: MIT */
/* SPDX-FileCopyrightText: 2023 Nicholas Chin */

#if defined(__linux__)
#include <sys/io.h>
#endif

#if defined(__OpenBSD__) || defined(__NetBSD__)
#include <sys/types.h>
#include <machine/sysarch.h>
#endif /* __OpenBSD__ || __NetBSD__ */

#if defined(__OpenBSD__)
#if defined(__amd64__)
#include <amd64/pio.h>
#elif defined(__i386__)
#include <i386/pio.h>
#endif /* __i386__ */
#endif /* __OpenBSD__ */

#if defined(__FreeBSD__)
#include <fcntl.h>
#include <sys/types.h>
#include <machine/cpufunc.h>
#include <unistd.h>
#endif /* __FreeBSD__ */

#include <errno.h>

#include "accessors.h"

uint32_t
pci_read_32(uint32_t dev, uint8_t reg)
{
	sys_outl(PCI_CFG_ADDR, dev | reg);
	return sys_inl(PCI_CFG_DATA);
}

void
pci_write_32(uint32_t dev, uint8_t reg, uint32_t value)
{
	sys_outl(PCI_CFG_ADDR, dev | reg);
	sys_outl(PCI_CFG_DATA, value);
}

void
sys_outb(unsigned int port, uint8_t data)
{
	#if defined(__linux__)
	outb(data, port);
	#endif
	#if defined(__OpenBSD__) || defined(__FreeBSD__)
	outb(port, data);
	#endif
	#if defined(__NetBSD__)
	__asm__ volatile ("outb %b0, %w1" : : "a"(data), "d"(port));
	#endif
}

void
sys_outl(unsigned int port, uint32_t data)
{
	#if defined(__linux__)
	outl(data, port);
	#endif
	#if defined(__OpenBSD__) || defined(__FreeBSD__)
	outl(port, data);
	#endif
	#if defined(__NetBSD__)
	__asm__ volatile ("outl %0, %w1" : : "a"(data), "d"(port));
	#endif
}

uint8_t
sys_inb(unsigned int port)
{
	#if defined(__linux__) || defined (__OpenBSD__) \
		|| defined(__FreeBSD__)
	return inb(port);
	#endif

	#if defined(__NetBSD__)
	uint8_t retval;
	__asm__ volatile ("inb %w1, %b0" : "=a" (retval) : "d" (port));
	return retval;
	#endif
	return 0;
}

uint32_t
sys_inl(unsigned int port)
{
	#if defined(__linux__) || defined (__OpenBSD__) \
		|| defined(__FreeBSD__)
	return inl(port);
	#endif
	#if defined(__NetBSD__)
	int retval;
	__asm__ volatile ("inl %w1, %0" : "=a" (retval) : "d" (port));
	return retval;
	#endif
	return 0;
}

int
sys_iopl(int level)
{
#if defined(__linux__)
	return iopl(level);
#endif
#if defined(__OpenBSD__)
#if defined(__i386__)
	return i386_iopl(level);
#elif defined(__amd64__)
	return amd64_iopl(level);
#endif /* __amd64__ */
#endif /* __OpenBSD__ */

#if defined(__NetBSD__)
#if defined(__i386__)
	return i386_iopl(level);
#elif defined(__amd64__)
	return x86_64_iopl(level);
#endif /* __amd64__ */
#endif /* __NetBSD__ */

#if defined(__FreeBSD__)
	/* Refer to io(4) manual page. This assumes the legacy behavior
	 * where opening /dev/io raises the IOPL of the process */
	static int io_fd = -1;

	/* Requesting privileged access */
	if (level > 0) {
		if (io_fd == -1) {
			io_fd = open("/dev/io", O_RDONLY);
			return (io_fd == -1) ? -1 : 0;
		}
	/* Lowering access to lowest level */
	} else if (level == 0 && io_fd != -1) {
		if (close(io_fd) == -1) {
			return -1;
		} else {
			io_fd = -1;
		}
	}
	return 0;
#endif /* __FreeBSD__ */

	errno = ENOSYS;
	return -1;
}