POK(kernelpart)
pci.c
Go to the documentation of this file.
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by laurent on Mon Jun 08 11:01:12 2009
15  */
16 
17 #ifdef POK_NEEDS_PCI
18 
19 # include <libc.h>
20 # include <arch/x86/pci.h>
21 
22 # include "gdt.h"
23 # include "event.h"
24 
25 static inline
26 unsigned int pci_read(unsigned int bus,
27  unsigned int dev,
28  unsigned int fun,
29  unsigned int reg)
30 {
31  unsigned int addr = (1 << 31) | (bus << 16) | (dev << 11) | (fun << 8) | (reg & 0xfc);
32  unsigned int val = -1;
33 
34  outl(PCI_CONFIG_ADDRESS, addr);
35  val = inl(PCI_CONFIG_DATA);
36 
37  return (val >> ((reg & 3) << 3));
38 }
39 
40 static inline
41 unsigned int pci_read_reg(s_pci_device* d,
42  unsigned int reg)
43 {
44  return (pci_read(d->bus, d->dev, d->fun, reg));
45 }
46 
47 static inline
48 int pci_open(s_pci_device* d)
49 {
50  unsigned int bus = 0;
51  unsigned int dev = 0;
52  unsigned int fun = 0;
53 
54  for (bus = 0; bus < PCI_BUS_MAX; bus++)
55  for (dev = 0; dev < PCI_DEV_MAX; dev++)
56  for (fun = 0; fun < PCI_FUN_MAX; fun++)
57  if (((unsigned short) pci_read(bus, dev, fun, PCI_REG_VENDORID)) == d->vendorid &&
58  ((unsigned short) pci_read(bus, dev, fun, PCI_REG_DEVICEID)) == d->deviceid)
59  {
60  // we do not handle type 1 or 2 PCI configuration spaces
61  if (pci_read(bus, dev, fun, PCI_REG_HEADERTYPE) != 0)
62  continue;
63 
64  d->bus = bus;
65  d->dev = dev;
66  d->fun = fun;
67  d->bar[0] = pci_read(bus, dev, fun, PCI_REG_BAR0);
68  d->irq_line = (unsigned char) pci_read_reg(d, PCI_REG_IRQLINE);
69 
70  return (0);
71  }
72 
73  return (-1);
74 }
75 
76 void pci_handler(void);
77 
78 void dummy_pci_handler(void)
79 {
80  __asm__ volatile
81  (
82  ".globl pci_handler\n"
83  "pci_handler:\n"
84  "push %eax\n" // save restricted context
85  "push %edx\n"
86  "mov $0x20, %al\n"
87  "mov $0xA0, %dx\n" // ack slave pic
88  "outb %al, %dx\n"
89  "mov $0x20, %dx\n" // ack master pic
90  "outb %al, %dx\n"
91  "pop %edx\n" // restore retricted context
92  "pop %eax\n"
93  "iret\n" // return
94  );
95 }
96 
97 void* ne2000_dev = NULL;
98 
99 pok_ret_t pci_register(s_pci_device* dev,
100  uint8_t part_id)
101 {
102  if (pci_open(dev) != 0)
103  return (-1);
104 
105  pok_partitions[part_id].io_min = (dev->bar[0] & (~0x1F));
106  pok_partitions[part_id].io_max = (dev->bar[0] & (~0x1F)) + dev->io_range;
107 
108  pok_idt_set_gate(32 + dev->irq_line,
110  (uint32_t) pci_handler,
112  0);
113 
114  ne2000_dev = dev;
115 
116  return (0);
117 }
118 
119 #endif /* POK_NEEDS_PCI */