]> 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 #include "hw_root_bus.h"
11 #include "phys_space.h"
12 #include "resource.h"
13 #include "cfg.h"
14
15 namespace {
16
17 // --- Root address space for IRQs -----------------------------------------
18 class Root_irq_rs : public Resource_space
19 {
20 public:
21   bool request(Resource *parent, Device *, Resource *child, Device *)
22   {
23     child->parent(parent);
24
25     return true;
26   };
27
28   bool alloc(Resource *, Device *, Resource *, Device *, bool)
29   { return false; }
30
31   ~Root_irq_rs() {}
32 };
33
34 // --- Root address space for IO-Ports --------------------------------------
35 class Root_io_rs : public Resource_space
36 {
37 public:
38   bool request(Resource *parent, Device *, Resource *child, Device *)
39   {
40     child->parent(parent);
41
42     return true;
43   }
44
45   bool alloc(Resource *parent, Device *, Resource *child, Device *, bool)
46   {
47     child->parent(parent);
48
49     return true;
50   }
51
52   ~Root_io_rs() {}
53 };
54
55
56 // --- Root address space for MMIO -----------------------------------------
57 class Root_mmio_rs : public Resource_space
58 {
59 public:
60   bool request(Resource *parent, Device *, Resource *child, Device *);
61   bool alloc(Resource *parent, Device *, Resource *child, Device *, bool);
62   ~Root_mmio_rs() {}
63 };
64
65 bool
66 Root_mmio_rs::request(Resource *parent, Device *, Resource *child, Device *)
67 {
68   //printf("request resource at root level: "); child->dump();
69   Adr_resource *x = dynamic_cast<Adr_resource*>(child);
70
71   if (x
72       && Phys_space::space.alloc(Phys_space::Phys_region(x->start(), x->end())))
73     {
74       child->parent(parent);
75       return true;
76     }
77
78 #if 1
79   printf("WARNING: phys mmio resource allocation failed\n");
80   child->dump();
81 #endif
82   return false;
83 }
84
85
86 bool
87 Root_mmio_rs::alloc(Resource *parent, Device *, Resource *child, Device *,
88                     bool /*resize*/)
89 {
90
91   Adr_resource *cld = dynamic_cast<Adr_resource *>(child);
92
93   if (!cld)
94     return false;
95
96   Adr_resource::Size align = cxx::max<Adr_resource::Size>(cld->alignment(),  L4_PAGESIZE - 1);
97   Phys_space::Phys_region phys = Phys_space::space.alloc(cld->size(), align);
98   if (!phys.valid())
99     {
100 #if 0
101       printf("ERROR: could not reserve physical space for resource\n");
102       r->dump();
103 #endif
104       cld->disable();
105       return false;
106     }
107
108   cld->start(phys.start());
109   child->parent(parent);
110
111   if (Io_config::cfg->verbose())
112     {
113       printf("allocated resource: ");
114       cld->dump();
115     }
116   return true;
117 }
118
119 // --- End Root address space for MMIO --------------------------------------
120 }
121
122 namespace Hw {
123
124 Root_bus::Root_bus(char const *name)
125 : Hw::Device(), _name(name)
126 {
127   // add root resource for IRQs
128   Root_resource *r = new Root_resource(Resource::Irq_res, new Root_irq_rs());
129   add_resource(r);
130
131   Resource_space *rs_mmio = new Root_mmio_rs();
132   // add root resource for non-prefetchable MMIO resources
133   r = new Root_resource(Resource::Mmio_res, rs_mmio);
134   r->add_flags(Adr_resource::F_width_64bit);
135   add_resource(r);
136
137   // add root resource for prefetchable MMIO resources
138   r = new Root_resource(Resource::Mmio_res | Resource::F_prefetchable, rs_mmio);
139   r->add_flags(Adr_resource::F_width_64bit);
140   add_resource(r);
141
142   // add root resource for IO ports
143   r = new Root_resource(Resource::Io_res, new Root_io_rs());
144   add_resource(r);
145 }
146
147 }