coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
pnp_device.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <stdint.h>
5 #include <arch/io.h>
6 #include <device/device.h>
7 #include <device/pnp.h>
8 
9 /* PNP config mode wrappers */
10 
11 void pnp_enter_conf_mode(struct device *dev)
12 {
13  if (dev->ops->ops_pnp_mode)
14  dev->ops->ops_pnp_mode->enter_conf_mode(dev);
15 }
16 
17 void pnp_exit_conf_mode(struct device *dev)
18 {
19  if (dev->ops->ops_pnp_mode)
20  dev->ops->ops_pnp_mode->exit_conf_mode(dev);
21 }
22 
23 #if CONFIG(HAVE_ACPI_TABLES)
24 void pnp_ssdt_enter_conf_mode(struct device *dev, const char *idx, const char *data)
25 {
26  if (dev->ops->ops_pnp_mode && dev->ops->ops_pnp_mode->ssdt_enter_conf_mode)
27  dev->ops->ops_pnp_mode->ssdt_enter_conf_mode(dev, idx, data);
28 }
29 void pnp_ssdt_exit_conf_mode(struct device *dev, const char *idx, const char *data)
30 {
31  if (dev->ops->ops_pnp_mode && dev->ops->ops_pnp_mode->ssdt_exit_conf_mode)
32  dev->ops->ops_pnp_mode->ssdt_exit_conf_mode(dev, idx, data);
33 }
34 #endif
35 
36 /* PNP fundamental operations */
37 
38 void pnp_write_config(struct device *dev, u8 reg, u8 value)
39 {
40  outb(reg, dev->path.pnp.port);
41  outb(value, dev->path.pnp.port + 1);
42 }
43 
44 u8 pnp_read_config(struct device *dev, u8 reg)
45 {
46  outb(reg, dev->path.pnp.port);
47  return inb(dev->path.pnp.port + 1);
48 }
49 
50 void pnp_unset_and_set_config(struct device *dev, u8 reg, u8 unset, u8 set)
51 {
52  outb(reg, dev->path.pnp.port);
53  u8 value = inb(dev->path.pnp.port + 1);
54  value &= ~unset;
55  value |= set;
56  outb(value, dev->path.pnp.port + 1);
57 }
58 
59 void pnp_set_logical_device(struct device *dev)
60 {
61  pnp_write_config(dev, 0x07, dev->path.pnp.device & 0xff);
62 }
63 
64 void pnp_set_enable(struct device *dev, int enable)
65 {
66  u8 tmp, bitpos;
67 
68  tmp = pnp_read_config(dev, PNP_IDX_EN);
69 
70  /* Handle virtual devices, which share the same LDN register. */
71  bitpos = (dev->path.pnp.device >> 8) & 0x7;
72 
73  if (enable)
74  tmp |= (1 << bitpos);
75  else
76  tmp &= ~(1 << bitpos);
77 
78  pnp_write_config(dev, PNP_IDX_EN, tmp);
79 }
80 
81 int pnp_read_enable(struct device *dev)
82 {
83  u8 tmp, bitpos;
84 
85  tmp = pnp_read_config(dev, PNP_IDX_EN);
86 
87  /* Handle virtual devices, which share the same LDN register. */
88  bitpos = (dev->path.pnp.device >> 8) & 0x7;
89 
90  return !!(tmp & (1 << bitpos));
91 }
92 
93 void pnp_set_iobase(struct device *dev, u8 index, u16 iobase)
94 {
95  /* Index == 0x60 or 0x62. */
96  pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
97  pnp_write_config(dev, index + 1, iobase & 0xff);
98 }
99 
100 void pnp_set_irq(struct device *dev, u8 index, u8 irq)
101 {
102  /* Index == 0x70 or 0x72. */
103  pnp_write_config(dev, index, irq);
104 }
105 
106 void pnp_set_drq(struct device *dev, u8 index, u8 drq)
107 {
108  /* Index == 0x74. */
109  pnp_write_config(dev, index, drq & 0xff);
110 }
111 
112 /* PNP device operations */
113 
114 void pnp_read_resources(struct device *dev)
115 {
116  return;
117 }
118 
119 static void pnp_set_resource(struct device *dev, struct resource *resource)
120 {
121  if (!(resource->flags & IORESOURCE_ASSIGNED)) {
122  /* The PNP_MSC Super IO registers have the IRQ flag set. If no
123  value is assigned in the devicetree, the corresponding
124  PNP_MSC register doesn't get written, which should be printed
125  as warning and not as error. */
126  if (resource->flags & IORESOURCE_IRQ &&
127  (resource->index != PNP_IDX_IRQ0) &&
129  printk(BIOS_WARNING, "%s %02lx %s size: "
130  "0x%010llx not assigned in devicetree\n", dev_path(dev),
132  resource->size);
133  else
134  printk(BIOS_ERR, "%s %02lx %s size: 0x%010llx "
135  "not assigned in devicetree\n", dev_path(dev), resource->index,
137  return;
138  }
139 
140  /* Now store the resource. */
141  if (resource->flags & IORESOURCE_IO) {
143  } else if (resource->flags & IORESOURCE_DRQ) {
145  } else if (resource->flags & IORESOURCE_IRQ) {
147  } else {
148  printk(BIOS_ERR, "%s %02lx unknown resource type\n",
149  dev_path(dev), resource->index);
150  return;
151  }
153 
155 }
156 
157 void pnp_set_resources(struct device *dev)
158 {
159  struct resource *res;
160 
161  pnp_enter_conf_mode(dev);
162 
163  /* Select the logical device (LDN). */
165 
166  /* Paranoia says I should disable the device here... */
167  for (res = dev->resource_list; res; res = res->next)
168  pnp_set_resource(dev, res);
169 
170  pnp_exit_conf_mode(dev);
171 }
172 
173 void pnp_enable_resources(struct device *dev)
174 {
175  pnp_enter_conf_mode(dev);
177  pnp_set_enable(dev, 1);
178  pnp_exit_conf_mode(dev);
179 }
180 
181 void pnp_enable(struct device *dev)
182 {
183  if (!dev->enabled) {
184  pnp_enter_conf_mode(dev);
186  pnp_set_enable(dev, 0);
187  pnp_exit_conf_mode(dev);
188  }
189 }
190 
191 void pnp_alt_enable(struct device *dev)
192 {
193  pnp_enter_conf_mode(dev);
195  pnp_set_enable(dev, !!dev->enabled);
196  pnp_exit_conf_mode(dev);
197 }
198 
199 struct device_operations pnp_ops = {
201  .set_resources = pnp_set_resources,
202  .enable_resources = pnp_enable_resources,
203  .enable = pnp_enable,
204 };
205 
206 /* PNP chip operations */
207 
208 static void pnp_get_ioresource(struct device *dev, u8 index, u16 mask)
209 {
210  struct resource *resource;
211  unsigned int bit;
212 
213  /* If none of the mask bits is set, the resource would occupy the whole
214  IO space leading to IO resource conflicts with the other devices */
215  if (!mask) {
216  printk(BIOS_ERR, "device %s index %d has no mask.\n",
217  dev_path(dev), index);
218  return;
219  }
220 
221  resource = new_resource(dev, index);
223 
224  /* Calculate IO region size which is determined by the first one from
225  the LSB of the mask. */
226  for (bit = 0; bit <= 15 && (mask & (1 << bit)) == 0; ++bit)
227  ;
228 
229  resource->gran = bit;
230  resource->align = bit;
231  resource->size = 1 << bit;
232 
233  /* Calculate IO region address limit which is determined by the first
234  one from the MSB of the mask. */
235  for (bit = 15; bit != 0 && (mask & (1 << bit)) == 0; --bit)
236  ;
237 
238  resource->limit = (1 << (bit + 1)) - 1;
239 
240  /* The block of ones in the mask is expected to be continuous.
241  If there is any zero in between the block of ones, it is ignored
242  in the calculation of the resource size and limit. */
243  if (mask != (resource->limit ^ (resource->size - 1)))
244  printk(BIOS_WARNING, "mask of device %s index %d is wrong.\n",
245  dev_path(dev), index);
246 }
247 
248 static void get_resources(struct device *dev, struct pnp_info *info)
249 {
250  struct resource *resource;
251 
252  if (info->flags & PNP_IO0)
253  pnp_get_ioresource(dev, PNP_IDX_IO0, info->io0);
254  if (info->flags & PNP_IO1)
255  pnp_get_ioresource(dev, PNP_IDX_IO1, info->io1);
256  if (info->flags & PNP_IO2)
257  pnp_get_ioresource(dev, PNP_IDX_IO2, info->io2);
258  if (info->flags & PNP_IO3)
259  pnp_get_ioresource(dev, PNP_IDX_IO3, info->io3);
260  if (info->flags & PNP_IO4)
261  pnp_get_ioresource(dev, PNP_IDX_IO4, info->io4);
262 
263  if (info->flags & PNP_IRQ0) {
265  resource->size = 1;
267  }
268  if (info->flags & PNP_IRQ1) {
270  resource->size = 1;
272  }
273 
274  if (info->flags & PNP_DRQ0) {
276  resource->size = 1;
278  }
279  if (info->flags & PNP_DRQ1) {
281  resource->size = 1;
283  }
284 
285  /*
286  * These are not IRQs, but set the flag to have the
287  * resource allocator do the right thing.
288  */
289  if (info->flags & PNP_EN) {
291  resource->size = 1;
293  }
294  if (info->flags & PNP_MSC0) {
296  resource->size = 1;
298  }
299  if (info->flags & PNP_MSC1) {
301  resource->size = 1;
303  }
304  if (info->flags & PNP_MSC2) {
306  resource->size = 1;
308  }
309  if (info->flags & PNP_MSC3) {
311  resource->size = 1;
313  }
314  if (info->flags & PNP_MSC4) {
316  resource->size = 1;
318  }
319  if (info->flags & PNP_MSC5) {
321  resource->size = 1;
323  }
324  if (info->flags & PNP_MSC6) {
326  resource->size = 1;
328  }
329  if (info->flags & PNP_MSC7) {
331  resource->size = 1;
333  }
334  if (info->flags & PNP_MSC8) {
336  resource->size = 1;
338  }
339  if (info->flags & PNP_MSC9) {
341  resource->size = 1;
343  }
344  if (info->flags & PNP_MSCA) {
346  resource->size = 1;
348  }
349  if (info->flags & PNP_MSCB) {
351  resource->size = 1;
353  }
354  if (info->flags & PNP_MSCC) {
356  resource->size = 1;
358  }
359  if (info->flags & PNP_MSCD) {
361  resource->size = 1;
363  }
364  if (info->flags & PNP_MSCE) {
366  resource->size = 1;
368  }
369 }
370 
371 void pnp_enable_devices(struct device *base_dev, struct device_operations *ops,
372  unsigned int functions, struct pnp_info *info)
373 {
374  struct device_path path;
375  struct device *dev;
376  int i;
377 
379  path.pnp.port = base_dev->path.pnp.port;
380 
381  /* Setup the ops and resources on the newly allocated devices. */
382  for (i = 0; i < functions; i++) {
383  /* Skip logical devices this Super I/O doesn't have. */
384  if (info[i].function == PNP_SKIP_FUNCTION)
385  continue;
386 
387  path.pnp.device = info[i].function;
388  dev = alloc_find_dev(base_dev->bus, &path);
389 
390  /* Don't initialize a device multiple times. */
391  if (dev->ops)
392  continue;
393 
394  /* use LDN-specific ops override from corresponding pnp_info
395  entry if not NULL */
396  if (info[i].ops)
397  dev->ops = info[i].ops;
398  /* else use device ops */
399  else
400  dev->ops = ops;
401 
402  get_resources(dev, &info[i]);
403  }
404 }
pte_t value
Definition: mmu.c:91
#define printk(level,...)
Definition: stdlib.h:16
struct device * alloc_find_dev(struct bus *parent, struct device_path *path)
See if a device structure already exists and if not allocate it.
Definition: device.c:138
u8 inb(u16 port)
void outb(u8 val, u16 port)
struct resource * new_resource(struct device *dev, unsigned int index)
See if a resource structure already exists for a given index and if not allocate one.
Definition: device_util.c:346
const char * resource_type(const struct resource *resource)
Return the resource type of a resource.
Definition: device_util.c:486
void report_resource_stored(struct device *dev, const struct resource *resource, const char *comment)
Print the resource that was just stored.
Definition: device_util.c:508
const char * dev_path(const struct device *dev)
Definition: device_util.c:149
static struct smmstore_params_info info
Definition: ramstage.c:12
static struct device_operations ops
Definition: ipmi_kcs_ops.c:416
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
@ DEVICE_PATH_PNP
Definition: path.h:10
#define PNP_MSC1
Definition: pnp.h:53
#define PNP_MSCD
Definition: pnp.h:65
#define PNP_MSC3
Definition: pnp.h:55
#define PNP_IRQ1
Definition: pnp.h:48
#define PNP_MSC7
Definition: pnp.h:59
#define PNP_MSCE
Definition: pnp.h:66
#define PNP_MSC9
Definition: pnp.h:61
#define PNP_MSC6
Definition: pnp.h:58
#define PNP_SKIP_FUNCTION
Definition: pnp.h:39
#define PNP_DRQ0
Definition: pnp.h:49
#define PNP_EN
Definition: pnp.h:51
#define PNP_MSCB
Definition: pnp.h:63
#define PNP_IO1
Definition: pnp.h:43
#define PNP_MSC8
Definition: pnp.h:60
#define PNP_IO2
Definition: pnp.h:44
#define PNP_IO4
Definition: pnp.h:46
#define PNP_IO0
Definition: pnp.h:42
#define PNP_IRQ0
Definition: pnp.h:47
#define PNP_IO3
Definition: pnp.h:45
#define PNP_MSC0
Definition: pnp.h:52
#define PNP_MSC2
Definition: pnp.h:54
#define PNP_MSCC
Definition: pnp.h:64
#define PNP_DRQ1
Definition: pnp.h:50
#define PNP_MSC4
Definition: pnp.h:56
#define PNP_MSC5
Definition: pnp.h:57
#define PNP_MSCA
Definition: pnp.h:62
#define PNP_IDX_MSC0
Definition: pnp_def.h:14
#define PNP_IDX_MSC9
Definition: pnp_def.h:23
#define PNP_IDX_MSC2
Definition: pnp_def.h:16
#define PNP_IDX_MSC3
Definition: pnp_def.h:17
#define PNP_IDX_MSCA
Definition: pnp_def.h:24
#define PNP_IDX_MSCB
Definition: pnp_def.h:25
#define PNP_IDX_IO2
Definition: pnp_def.h:7
#define PNP_IDX_DRQ0
Definition: pnp_def.h:12
#define PNP_IDX_DRQ1
Definition: pnp_def.h:13
#define PNP_IDX_MSC5
Definition: pnp_def.h:19
#define PNP_IDX_MSC4
Definition: pnp_def.h:18
#define PNP_IDX_IO4
Definition: pnp_def.h:9
#define PNP_IDX_IRQ1
Definition: pnp_def.h:11
#define PNP_IDX_EN
Definition: pnp_def.h:4
#define PNP_IDX_MSCD
Definition: pnp_def.h:27
#define PNP_IDX_IO3
Definition: pnp_def.h:8
#define PNP_IDX_MSC8
Definition: pnp_def.h:22
#define PNP_IDX_MSCC
Definition: pnp_def.h:26
#define PNP_IDX_MSC1
Definition: pnp_def.h:15
#define PNP_IDX_MSC6
Definition: pnp_def.h:20
#define PNP_IDX_MSC7
Definition: pnp_def.h:21
#define PNP_IDX_MSCE
Definition: pnp_def.h:28
#define PNP_IDX_IO0
Definition: pnp_def.h:5
#define PNP_IDX_IO1
Definition: pnp_def.h:6
#define PNP_IDX_IRQ0
Definition: pnp_def.h:10
void pnp_exit_conf_mode(struct device *dev)
Definition: pnp_device.c:17
void pnp_enable(struct device *dev)
Definition: pnp_device.c:181
int pnp_read_enable(struct device *dev)
Definition: pnp_device.c:81
void pnp_read_resources(struct device *dev)
Definition: pnp_device.c:114
void pnp_enable_devices(struct device *base_dev, struct device_operations *ops, unsigned int functions, struct pnp_info *info)
Definition: pnp_device.c:371
struct device_operations pnp_ops
Definition: pnp_device.c:199
void pnp_set_irq(struct device *dev, u8 index, u8 irq)
Definition: pnp_device.c:100
void pnp_set_logical_device(struct device *dev)
Definition: pnp_device.c:59
static void pnp_set_resource(struct device *dev, struct resource *resource)
Definition: pnp_device.c:119
void pnp_set_enable(struct device *dev, int enable)
Definition: pnp_device.c:64
void pnp_set_resources(struct device *dev)
Definition: pnp_device.c:157
void pnp_set_drq(struct device *dev, u8 index, u8 drq)
Definition: pnp_device.c:106
void pnp_alt_enable(struct device *dev)
Definition: pnp_device.c:191
u8 pnp_read_config(struct device *dev, u8 reg)
Definition: pnp_device.c:44
void pnp_unset_and_set_config(struct device *dev, u8 reg, u8 unset, u8 set)
Definition: pnp_device.c:50
void pnp_set_iobase(struct device *dev, u8 index, u16 iobase)
Definition: pnp_device.c:93
static void get_resources(struct device *dev, struct pnp_info *info)
Definition: pnp_device.c:248
void pnp_enter_conf_mode(struct device *dev)
Definition: pnp_device.c:11
static void pnp_get_ioresource(struct device *dev, u8 index, u16 mask)
Definition: pnp_device.c:208
void pnp_write_config(struct device *dev, u8 reg, u8 value)
Definition: pnp_device.c:38
void pnp_enable_resources(struct device *dev)
Definition: pnp_device.c:173
#define IORESOURCE_IRQ
Definition: resource.h:11
#define IORESOURCE_DRQ
Definition: resource.h:12
#define IORESOURCE_STORED
Definition: resource.h:32
#define IORESOURCE_ASSIGNED
Definition: resource.h:34
#define IORESOURCE_IO
Definition: resource.h:9
static const int mask[4]
Definition: gpio.c:308
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
void(* read_resources)(struct device *dev)
Definition: device.h:39
const struct pnp_mode_ops * ops_pnp_mode
Definition: device.h:66
struct pnp_path pnp
Definition: path.h:117
enum device_path_type type
Definition: path.h:114
Definition: device.h:107
struct device_path path
Definition: device.h:115
struct device_operations * ops
Definition: device.h:143
DEVTREE_CONST struct bus * bus
Definition: device.h:108
DEVTREE_CONST struct resource * resource_list
Definition: device.h:134
unsigned int enabled
Definition: device.h:122
Definition: pnp.h:37
void(* enter_conf_mode)(struct device *dev)
Definition: pnp.h:74
void(* exit_conf_mode)(struct device *dev)
Definition: pnp.h:75
unsigned int port
Definition: path.h:58
unsigned int device
Definition: path.h:59
unsigned long flags
Definition: resource.h:49
unsigned char align
Definition: resource.h:51
resource_t limit
Definition: resource.h:47
unsigned char gran
Definition: resource.h:52
resource_t base
Definition: resource.h:45
unsigned long index
Definition: resource.h:50
resource_t size
Definition: resource.h:46
DEVTREE_CONST struct resource * next
Definition: resource.h:48