1*c2e0c6b5SAndroid Build Coastguard Worker /*
2*c2e0c6b5SAndroid Build Coastguard Worker * The PCI Library -- Access to i386 I/O ports on Haiku
3*c2e0c6b5SAndroid Build Coastguard Worker *
4*c2e0c6b5SAndroid Build Coastguard Worker * Copyright (c) 2009 Francois Revol <[email protected]>
5*c2e0c6b5SAndroid Build Coastguard Worker *
6*c2e0c6b5SAndroid Build Coastguard Worker * Can be freely distributed and used under the terms of the GNU GPL v2+
7*c2e0c6b5SAndroid Build Coastguard Worker *
8*c2e0c6b5SAndroid Build Coastguard Worker * SPDX-License-Identifier: GPL-2.0-or-later
9*c2e0c6b5SAndroid Build Coastguard Worker */
10*c2e0c6b5SAndroid Build Coastguard Worker
11*c2e0c6b5SAndroid Build Coastguard Worker #include <Drivers.h>
12*c2e0c6b5SAndroid Build Coastguard Worker #include <ISA.h>
13*c2e0c6b5SAndroid Build Coastguard Worker #include <PCI.h>
14*c2e0c6b5SAndroid Build Coastguard Worker
15*c2e0c6b5SAndroid Build Coastguard Worker /* from haiku/trunk/headers/private/drivers/poke.h */
16*c2e0c6b5SAndroid Build Coastguard Worker
17*c2e0c6b5SAndroid Build Coastguard Worker #define POKE_DEVICE_NAME "poke"
18*c2e0c6b5SAndroid Build Coastguard Worker #define POKE_DEVICE_FULLNAME "/dev/misc/poke"
19*c2e0c6b5SAndroid Build Coastguard Worker #define POKE_SIGNATURE 'wltp' // "We Like To Poke"
20*c2e0c6b5SAndroid Build Coastguard Worker
21*c2e0c6b5SAndroid Build Coastguard Worker enum {
22*c2e0c6b5SAndroid Build Coastguard Worker POKE_PORT_READ = B_DEVICE_OP_CODES_END + 1,
23*c2e0c6b5SAndroid Build Coastguard Worker POKE_PORT_WRITE,
24*c2e0c6b5SAndroid Build Coastguard Worker POKE_PORT_INDEXED_READ,
25*c2e0c6b5SAndroid Build Coastguard Worker POKE_PORT_INDEXED_WRITE,
26*c2e0c6b5SAndroid Build Coastguard Worker POKE_PCI_READ_CONFIG,
27*c2e0c6b5SAndroid Build Coastguard Worker POKE_PCI_WRITE_CONFIG,
28*c2e0c6b5SAndroid Build Coastguard Worker POKE_GET_NTH_PCI_INFO,
29*c2e0c6b5SAndroid Build Coastguard Worker POKE_GET_PHYSICAL_ADDRESS,
30*c2e0c6b5SAndroid Build Coastguard Worker POKE_MAP_MEMORY,
31*c2e0c6b5SAndroid Build Coastguard Worker POKE_UNMAP_MEMORY
32*c2e0c6b5SAndroid Build Coastguard Worker };
33*c2e0c6b5SAndroid Build Coastguard Worker
34*c2e0c6b5SAndroid Build Coastguard Worker
35*c2e0c6b5SAndroid Build Coastguard Worker typedef struct {
36*c2e0c6b5SAndroid Build Coastguard Worker uint32 signature;
37*c2e0c6b5SAndroid Build Coastguard Worker uint8 index;
38*c2e0c6b5SAndroid Build Coastguard Worker pci_info* info;
39*c2e0c6b5SAndroid Build Coastguard Worker status_t status;
40*c2e0c6b5SAndroid Build Coastguard Worker } pci_info_args;
41*c2e0c6b5SAndroid Build Coastguard Worker
42*c2e0c6b5SAndroid Build Coastguard Worker
43*c2e0c6b5SAndroid Build Coastguard Worker typedef struct {
44*c2e0c6b5SAndroid Build Coastguard Worker uint32 signature;
45*c2e0c6b5SAndroid Build Coastguard Worker uint16 port;
46*c2e0c6b5SAndroid Build Coastguard Worker uint8 size; // == index for POKE_PORT_INDEXED_*
47*c2e0c6b5SAndroid Build Coastguard Worker uint32 value;
48*c2e0c6b5SAndroid Build Coastguard Worker } port_io_args;
49*c2e0c6b5SAndroid Build Coastguard Worker
50*c2e0c6b5SAndroid Build Coastguard Worker
51*c2e0c6b5SAndroid Build Coastguard Worker typedef struct {
52*c2e0c6b5SAndroid Build Coastguard Worker uint32 signature;
53*c2e0c6b5SAndroid Build Coastguard Worker uint8 bus;
54*c2e0c6b5SAndroid Build Coastguard Worker uint8 device;
55*c2e0c6b5SAndroid Build Coastguard Worker uint8 function;
56*c2e0c6b5SAndroid Build Coastguard Worker uint8 size;
57*c2e0c6b5SAndroid Build Coastguard Worker uint8 offset;
58*c2e0c6b5SAndroid Build Coastguard Worker uint32 value;
59*c2e0c6b5SAndroid Build Coastguard Worker } pci_io_args;
60*c2e0c6b5SAndroid Build Coastguard Worker
61*c2e0c6b5SAndroid Build Coastguard Worker
62*c2e0c6b5SAndroid Build Coastguard Worker /* en poke.h*/
63*c2e0c6b5SAndroid Build Coastguard Worker
64*c2e0c6b5SAndroid Build Coastguard Worker static int poke_driver_fd;
65*c2e0c6b5SAndroid Build Coastguard Worker
66*c2e0c6b5SAndroid Build Coastguard Worker static int
intel_setup_io(struct pci_access * a UNUSED)67*c2e0c6b5SAndroid Build Coastguard Worker intel_setup_io(struct pci_access *a UNUSED)
68*c2e0c6b5SAndroid Build Coastguard Worker {
69*c2e0c6b5SAndroid Build Coastguard Worker /*
70*c2e0c6b5SAndroid Build Coastguard Worker * Opening poke device on systems with the linked change below
71*c2e0c6b5SAndroid Build Coastguard Worker * automatically changes process IOPL to 3 and closing its file
72*c2e0c6b5SAndroid Build Coastguard Worker * descriptor changes process IOPL back to 0, which give access
73*c2e0c6b5SAndroid Build Coastguard Worker * to all x86 IO ports via x86 in/out instructions for this
74*c2e0c6b5SAndroid Build Coastguard Worker * userspace process. To support also older systems without this
75*c2e0c6b5SAndroid Build Coastguard Worker * change, access IO ports via ioctl() instead of x86 in/out.
76*c2e0c6b5SAndroid Build Coastguard Worker * https://review.haiku-os.org/c/haiku/+/1077
77*c2e0c6b5SAndroid Build Coastguard Worker */
78*c2e0c6b5SAndroid Build Coastguard Worker poke_driver_fd = open(POKE_DEVICE_FULLNAME, O_RDWR);
79*c2e0c6b5SAndroid Build Coastguard Worker return (poke_driver_fd < 0) ? 0 : 1;
80*c2e0c6b5SAndroid Build Coastguard Worker }
81*c2e0c6b5SAndroid Build Coastguard Worker
82*c2e0c6b5SAndroid Build Coastguard Worker static inline void
intel_cleanup_io(struct pci_access * a UNUSED)83*c2e0c6b5SAndroid Build Coastguard Worker intel_cleanup_io(struct pci_access *a UNUSED)
84*c2e0c6b5SAndroid Build Coastguard Worker {
85*c2e0c6b5SAndroid Build Coastguard Worker close(poke_driver_fd);
86*c2e0c6b5SAndroid Build Coastguard Worker }
87*c2e0c6b5SAndroid Build Coastguard Worker
88*c2e0c6b5SAndroid Build Coastguard Worker static inline u8
intel_inb(u16 port)89*c2e0c6b5SAndroid Build Coastguard Worker intel_inb (u16 port)
90*c2e0c6b5SAndroid Build Coastguard Worker {
91*c2e0c6b5SAndroid Build Coastguard Worker port_io_args args = { POKE_SIGNATURE, port, sizeof(u8), 0 };
92*c2e0c6b5SAndroid Build Coastguard Worker if (ioctl(poke_driver_fd, POKE_PORT_READ, &args, sizeof(args)) < 0)
93*c2e0c6b5SAndroid Build Coastguard Worker return 0;
94*c2e0c6b5SAndroid Build Coastguard Worker return (u8)args.value;
95*c2e0c6b5SAndroid Build Coastguard Worker }
96*c2e0c6b5SAndroid Build Coastguard Worker
97*c2e0c6b5SAndroid Build Coastguard Worker static inline u16
intel_inw(u16 port)98*c2e0c6b5SAndroid Build Coastguard Worker intel_inw (u16 port)
99*c2e0c6b5SAndroid Build Coastguard Worker {
100*c2e0c6b5SAndroid Build Coastguard Worker port_io_args args = { POKE_SIGNATURE, port, sizeof(u16), 0 };
101*c2e0c6b5SAndroid Build Coastguard Worker if (ioctl(poke_driver_fd, POKE_PORT_READ, &args, sizeof(args)) < 0)
102*c2e0c6b5SAndroid Build Coastguard Worker return 0;
103*c2e0c6b5SAndroid Build Coastguard Worker return (u16)args.value;
104*c2e0c6b5SAndroid Build Coastguard Worker }
105*c2e0c6b5SAndroid Build Coastguard Worker
106*c2e0c6b5SAndroid Build Coastguard Worker static inline u32
intel_inl(u16 port)107*c2e0c6b5SAndroid Build Coastguard Worker intel_inl (u16 port)
108*c2e0c6b5SAndroid Build Coastguard Worker {
109*c2e0c6b5SAndroid Build Coastguard Worker port_io_args args = { POKE_SIGNATURE, port, sizeof(u32), 0 };
110*c2e0c6b5SAndroid Build Coastguard Worker if (ioctl(poke_driver_fd, POKE_PORT_READ, &args, sizeof(args)) < 0)
111*c2e0c6b5SAndroid Build Coastguard Worker return 0;
112*c2e0c6b5SAndroid Build Coastguard Worker return (u32)args.value;
113*c2e0c6b5SAndroid Build Coastguard Worker }
114*c2e0c6b5SAndroid Build Coastguard Worker
115*c2e0c6b5SAndroid Build Coastguard Worker static inline void
intel_outb(u8 value,u16 port)116*c2e0c6b5SAndroid Build Coastguard Worker intel_outb (u8 value, u16 port)
117*c2e0c6b5SAndroid Build Coastguard Worker {
118*c2e0c6b5SAndroid Build Coastguard Worker port_io_args args = { POKE_SIGNATURE, port, sizeof(u8), value };
119*c2e0c6b5SAndroid Build Coastguard Worker ioctl(poke_driver_fd, POKE_PORT_WRITE, &args, sizeof(args));
120*c2e0c6b5SAndroid Build Coastguard Worker }
121*c2e0c6b5SAndroid Build Coastguard Worker
122*c2e0c6b5SAndroid Build Coastguard Worker static inline void
intel_outw(u16 value,u16 port)123*c2e0c6b5SAndroid Build Coastguard Worker intel_outw (u16 value, u16 port)
124*c2e0c6b5SAndroid Build Coastguard Worker {
125*c2e0c6b5SAndroid Build Coastguard Worker port_io_args args = { POKE_SIGNATURE, port, sizeof(u16), value };
126*c2e0c6b5SAndroid Build Coastguard Worker ioctl(poke_driver_fd, POKE_PORT_WRITE, &args, sizeof(args));
127*c2e0c6b5SAndroid Build Coastguard Worker }
128*c2e0c6b5SAndroid Build Coastguard Worker
129*c2e0c6b5SAndroid Build Coastguard Worker static inline void
intel_outl(u32 value,u16 port)130*c2e0c6b5SAndroid Build Coastguard Worker intel_outl (u32 value, u16 port)
131*c2e0c6b5SAndroid Build Coastguard Worker {
132*c2e0c6b5SAndroid Build Coastguard Worker port_io_args args = { POKE_SIGNATURE, port, sizeof(u32), value };
133*c2e0c6b5SAndroid Build Coastguard Worker ioctl(poke_driver_fd, POKE_PORT_WRITE, &args, sizeof(args));
134*c2e0c6b5SAndroid Build Coastguard Worker }
135*c2e0c6b5SAndroid Build Coastguard Worker
intel_io_lock(void)136*c2e0c6b5SAndroid Build Coastguard Worker static inline void intel_io_lock(void)
137*c2e0c6b5SAndroid Build Coastguard Worker {
138*c2e0c6b5SAndroid Build Coastguard Worker }
139*c2e0c6b5SAndroid Build Coastguard Worker
intel_io_unlock(void)140*c2e0c6b5SAndroid Build Coastguard Worker static inline void intel_io_unlock(void)
141*c2e0c6b5SAndroid Build Coastguard Worker {
142*c2e0c6b5SAndroid Build Coastguard Worker }
143