]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/vpci_pci_bridge.cc
update
[l4.git] / l4 / pkg / io / server / src / vpci_pci_bridge.cc
1 /*
2  * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
3  *     economic rights: Technische Universität Dresden (Germany)
4  *
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU General Public License 2.
7  * Please see the COPYING-GPL-2 file for details.
8  */
9
10 #include "vpci_pci_bridge.h"
11 #include "vbus_factory.h"
12
13 namespace Vi {
14
15 Pci_to_pci_bridge::Pci_to_pci_bridge()
16 {
17   add_feature(this);
18   _h = &_cfg_space[0];
19   _h_len = sizeof(_cfg_space);
20   cfg_hdr()->hdr_type = 1;
21   cfg_hdr()->vendor_device = 0x02000400;
22   cfg_hdr()->status = 0;
23   cfg_hdr()->class_rev = 0x06040000;
24   cfg_hdr()->cmd = 0x3;
25
26   cfg_write(::Pci_dev::C_primary, 0x00010100, Hw::Pci::Cfg_long);
27
28   Bridge_cfg *bc = bridge_cfg();
29   bc->io_base = 0xc0;      bc->io_base_upper = 0;
30   bc->io_limit = 0xf0;  bc->io_limit_upper = 0;
31   bc->mem_base = 0xa000;
32   bc->mem_limit = 0xeff0;
33   bc->pref_base = 0xf001; bc->pref_base_upper = 0;
34   bc->pref_limit = 0xfff1; bc->pref_limit_upper = 0; //0xffffffff;
35 }
36
37
38 int
39 Pci_to_pci_bridge::cfg_read(int reg, l4_uint32_t *v, Cfg_width o)
40 {
41   unsigned mask = ~0U >> (32 - (1U << (o + 3)));
42   switch (reg & ~3)
43     {
44     case 0x18: // bus config stuff
45       *v = (_bus_config >> ((reg & 3)*8)) & mask;
46       return L4_EOK;
47
48     case 0x10: // We have no BARs
49     case 0x14:
50     case 0x38:
51       *v = 0;
52       return L4_EOK;
53
54     default:
55       break;
56     }
57
58   return Pci_virtual_dev::cfg_read(reg, v, o);
59 }
60
61
62 int
63 Pci_to_pci_bridge::cfg_write(int reg, l4_uint32_t v, Cfg_width o)
64 {
65   unsigned mask = (~0U >> (32 - (1U << (o + 3)))) << ((reg & 3) * 8);
66   switch (reg & ~3)
67     {
68     case 0x18:
69       _bus_config = (_bus_config & ~mask) | ((v << ((reg & 3)*8)) & mask);
70       return L4_EOK;
71
72     case 0x10: // We have no BARs
73     case 0x14:
74     case 0x38:
75       return L4_EOK;
76
77     default:
78       break;
79     }
80   int r = Pci_virtual_dev::cfg_write(reg, v, o);
81
82   switch (reg & ~3)
83     {
84     case 0x1c:
85       *(l4_uint32_t*)(_h + 0x1c) &= 0x0000f000;
86       break;
87     case 0x24:
88       *(l4_uint32_t*)(_h + 0x24) &= 0xfff0fff0;
89       *(l4_uint32_t*)(_h + 0x24) |= 0x00010001;
90       break;
91     case 0x22:
92       *(l4_uint32_t*)(_h + 0x22) &= 0xfff0fff0;
93       break;
94     }
95
96   return r;
97 }
98
99
100 static Dev_factory_t<Pci_to_pci_bridge> __pci_to_pci_factory("PCI_PCI_bridge");
101
102 }