]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/fb-drv/server/src/vesa.cc
Some minor fixes.
[l4.git] / l4 / pkg / fb-drv / server / src / vesa.cc
1 /*
2  * (c) 2009 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 <l4/x86emu/int10.h>
12 #include <l4/vbus/vbus>
13 #include <l4/vbus/vbus_inhibitor.h>
14
15 #include <l4/re/env>
16 #include <l4/re/error_helper>
17 #include <l4/re/util/event>
18 #include <l4/re/event_enums.h>
19
20 #include "fb.h"
21 #include "splash.h"
22
23 #include <cstdio>
24
25 class Vesa_fb : public Phys_fb
26 {
27 private:
28   struct Vbus_handler : L4::Irqep_t<Vbus_handler>
29   {
30     Vbus_handler(Vesa_fb *f) : fb(f) {}
31     Vesa_fb *fb;
32     void handle_irq();
33   };
34
35   L4Re::Util::Event _vbus_event;
36   Vbus_handler _vbus_irq;
37   L4::Cap<L4vbus::Vbus> _vbus;
38   int _vbemode = 0;
39
40 public:
41   Vesa_fb() : _vbus_irq(this) {}
42
43   bool setup_drv(Prog_args *pa, L4Re::Util::Object_registry *r);
44 };
45
46 void Vesa_fb::Vbus_handler::handle_irq()
47 {
48   l4util_mb_vbe_ctrl_t vbe;
49   l4util_mb_vbe_mode_t vbi;
50   L4Re::Event_buffer::Event *e;
51   while ((e = fb->_vbus_event.buffer().next()) != NULL)
52     {
53       if (e->payload.type != L4RE_EV_PM)
54         continue;
55
56       switch (e->payload.code)
57         {
58           case L4VBUS_INHIBITOR_SUSPEND:
59             printf("Received suspend event.\n");
60             fb->_vbus->acquire(L4VBUS_INHIBITOR_WAKEUP, "restart video on wakeup");
61             fb->_vbus->L4Re::Inhibitor::release(L4VBUS_INHIBITOR_SUSPEND);
62             break;
63           case L4VBUS_INHIBITOR_WAKEUP:
64             printf("Received wakeup event.\n");
65             fb->_vbus->acquire(L4VBUS_INHIBITOR_SUSPEND, "GFX running");
66             fb->_vbus->L4Re::Inhibitor::release(L4VBUS_INHIBITOR_WAKEUP);
67             if (fb->_vbemode > 0)
68               {
69                 int res = x86emu_int10_set_vbemode(fb->_vbemode, &vbe, &vbi);
70                 if (res < 0)
71                   printf("error: could not setup VESA mode on resume: %d\n", res);
72               }
73             break;
74           default:
75             break;
76         }
77     }
78 }
79
80
81 Phys_fb *Phys_fb::probe()
82 {
83   return new Vesa_fb();
84 }
85
86 bool
87 Vesa_fb::setup_drv(Prog_args *pa, L4Re::Util::Object_registry *r)
88 {
89   l4util_mb_vbe_ctrl_t vbe;
90   l4util_mb_vbe_mode_t vbi;
91   _vbus = L4Re::chkcap(L4Re::Env::env()->get_cap<L4vbus::Vbus>("vbus"), "request V-BUS cap");
92   _vbus_event.init<L4::Irq>(_vbus);
93   r->register_irq_obj(&_vbus_irq, L4::cap_cast<L4::Irq>(_vbus_event.irq()));
94
95   _vbus->acquire(L4VBUS_INHIBITOR_SUSPEND, "GFX running");
96
97   int res = x86emu_int10_set_vbemode(pa->vbemode, &vbe, &vbi);
98   if (res < 0)
99     return false;
100
101   _vbemode = res;
102
103   _vidmem_size = 64*1024*vbe.total_memory;
104
105   _vidmem_start = 0;
106   int error;
107   error = L4Re::Env::env()->rm()->attach(&_vidmem_start, _vidmem_size,
108                                          L4Re::Rm::Search_addr | L4Re::Rm::Eager_map,
109                                          _vbus, vbi.phys_base, 20);
110
111   if (error)
112     printf("map of gfx mem failed\n");
113
114   _vidmem_end   = _vidmem_start + _vidmem_size;
115
116   _screen_info.width = vbi.x_resolution;
117   _screen_info.height = vbi.y_resolution;
118   _screen_info.flags = L4Re::Video::Goos::F_auto_refresh;
119   _screen_info.pixel_info = L4Re::Video::Pixel_info(&vbi);
120
121   _view_info.buffer_offset = 0; //base_offset;
122   _view_info.bytes_per_line = vbi.bytes_per_scanline;
123
124   init_infos();
125
126   printf("Framebuffer memory: phys: %x - %lx\n",
127          vbi.phys_base, vbi.phys_base + _vidmem_size);
128   printf("                    virt: %lx - %lx\n",
129          _vidmem_start, _vidmem_start + _vidmem_size);
130
131   splash_display(&_view_info, _vidmem_start);
132
133   return true;
134 }