]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/hw_root_bus.cc
update
[l4.git] / l4 / pkg / io / server / src / hw_root_bus.cc
1 /*
2  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *          Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10
11 #include "cfg.h"
12 #include "debug.h"
13 #include "hw_root_bus.h"
14 #include "phys_space.h"
15 #include "resource.h"
16
17 namespace {
18
19 // --- Root address space for IRQs -----------------------------------------
20 class Root_irq_rs : public Resource_space
21 {
22 public:
23   bool request(Resource *parent, Device *, Resource *child, Device *)
24   {
25     child->parent(parent);
26
27     return true;
28   };
29
30   bool alloc(Resource *, Device *, Resource *, Device *, bool)
31   { return false; }
32
33   ~Root_irq_rs() {}
34 };
35
36 // --- Root address space for IO-Ports --------------------------------------
37 class Root_io_rs : public Resource_space
38 {
39 public:
40   bool request(Resource *parent, Device *, Resource *child, Device *)
41   {
42     child->parent(parent);
43
44     return true;
45   }
46
47   bool alloc(Resource *parent, Device *, Resource *child, Device *, bool)
48   {
49     child->parent(parent);
50
51     return true;
52   }
53
54   ~Root_io_rs() {}
55 };
56
57
58 // --- Root address space for MMIO -----------------------------------------
59 class Root_mmio_rs : public Resource_space
60 {
61 public:
62   bool request(Resource *parent, Device *, Resource *child, Device *);
63   bool alloc(Resource *parent, Device *, Resource *child, Device *, bool);
64   ~Root_mmio_rs() {}
65 };
66
67 bool
68 Root_mmio_rs::request(Resource *parent, Device *, Resource *child, Device *)
69 {
70   //printf("request resource at root level: "); child->dump();
71   Adr_resource *x = dynamic_cast<Adr_resource*>(child);
72
73   if (x
74       && Phys_space::space.alloc(Phys_space::Phys_region(x->start(), x->end())))
75     {
76       child->parent(parent);
77       return true;
78     }
79
80   d_printf(DBG_WARN, "WARNING: phys mmio resource allocation failed\n");
81   if (dlevel(DBG_WARN))
82     child->dump();
83
84   return false;
85 }
86
87
88 bool
89 Root_mmio_rs::alloc(Resource *parent, Device *, Resource *child, Device *,
90                     bool /*resize*/)
91 {
92
93   Adr_resource *cld = dynamic_cast<Adr_resource *>(child);
94
95   if (!cld)
96     return false;
97
98   Adr_resource::Size align = cxx::max<Adr_resource::Size>(cld->alignment(),  L4_PAGESIZE - 1);
99   Phys_space::Phys_region phys = Phys_space::space.alloc(cld->size(), align);
100   if (!phys.valid())
101     {
102 #if 0
103       printf("ERROR: could not reserve physical space for resource\n");
104       r->dump();
105 #endif
106       cld->disable();
107       return false;
108     }
109
110   cld->start(phys.start());
111   child->parent(parent);
112
113   if (dlevel(DBG_DEBUG))
114     {
115       printf("allocated resource: ");
116       cld->dump();
117     }
118   return true;
119 }
120
121 // --- End Root address space for MMIO --------------------------------------
122 }
123
124 namespace Hw {
125
126 Root_bus::Root_bus(char const *name)
127 : Hw::Device(), _name(name)
128 {
129   // add root resource for IRQs
130   Root_resource *r = new Root_resource(Resource::Irq_res, new Root_irq_rs());
131   add_resource(r);
132
133   Resource_space *rs_mmio = new Root_mmio_rs();
134   // add root resource for non-prefetchable MMIO resources
135   r = new Root_resource(Resource::Mmio_res, rs_mmio);
136   r->add_flags(Adr_resource::F_width_64bit);
137   add_resource(r);
138
139   // add root resource for prefetchable MMIO resources
140   r = new Root_resource(Resource::Mmio_res | Resource::F_prefetchable, rs_mmio);
141   r->add_flags(Adr_resource::F_width_64bit);
142   add_resource(r);
143
144   // add root resource for IO ports
145   r = new Root_resource(Resource::Io_res, new Root_io_rs());
146   add_resource(r);
147 }
148
149 }