1 /*
2  * (c) 2008-2009 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 #include <l4/util/mb_info.h>
10 #include <l4/sys/consts.h>
11 
12 #include <l4/re/dataspace>
13 #include <l4/re/video/goos>
14 
15 #include <l4/sigma0/sigma0.h>
16 
17 #include <l4/cxx/iostream>
18 #include <l4/cxx/l4iostream>
19 
20 #include "dataspace_static.h"
21 #include "globals.h"
22 #include "name_space.h"
23 #include "page_alloc.h"
24 #include "pages.h"
25 #include "vesa_fb.h"
26 
27 #include <l4/re/util/video/goos_svr>
28 #include <l4/sys/cxx/ipc_epiface>
29 
30 using L4Re::Dataspace;
31 
32 class Vesa_fb :
33   public L4Re::Util::Video::Goos_svr,
34   public L4::Epiface_t<Vesa_fb, L4Re::Video::Goos, Moe::Server_object>
35 {
36 private:
37   l4util_mb_vbe_ctrl_t *vbe;
38   l4util_mb_vbe_mode_t *vbi;
39   unsigned long base_offset;
40   unsigned long map_size;
41 
42 public:
43   Vesa_fb(l4util_l4mod_info *mbi);
~Vesa_fb()44   virtual ~Vesa_fb() {}
45 };
46 
47 void
init_vesa_fb(l4util_l4mod_info * mbi)48 init_vesa_fb(l4util_l4mod_info *mbi)
49 {
50   static Vesa_fb video(mbi);
51   (void)video;
52 }
53 
Vesa_fb(l4util_l4mod_info * mbi)54 Vesa_fb::Vesa_fb(l4util_l4mod_info *mbi)
55 {
56   vbe = (l4util_mb_vbe_ctrl_t*)(unsigned long)mbi->vbe_ctrl_info;
57   vbi = (l4util_mb_vbe_mode_t*)(unsigned long)mbi->vbe_mode_info;
58   if (!vbe && !vbi)
59     return;
60 
61   base_offset = vbi->phys_base & (L4_SUPERPAGESIZE - 1);
62   unsigned long paddr = vbi->phys_base & ~(L4_SUPERPAGESIZE - 1);
63   unsigned long fb_size = 64 * 1024 * vbe->total_memory;
64   map_size = (fb_size + base_offset + L4_SUPERPAGESIZE - 1)
65              & ~(L4_SUPERPAGESIZE - 1);
66 
67   unsigned long vaddr
68       = l4_round_size(Moe::Pages::max_addr, L4_SUPERPAGESHIFT);
69   if (vaddr >= Moe::Virt_limit::end - map_size - L4_SUPERPAGESIZE)
70     vaddr = (unsigned long)Single_page_alloc_base::_alloc(map_size);
71   if (vaddr == 0)
72     {
73       L4::cerr << "Failed to get memory for VESA video memory\n";
74       return;
75     }
76 
77   switch (l4sigma0_map_iomem(Sigma0_cap, paddr, vaddr, map_size, 1))
78     {
79     case -2:
80       L4::cerr << "IPC error mapping video memory\n";
81       return;
82     case -3:
83       L4::cerr << "No fpage received\n";
84       return;
85     default:
86       break;
87     }
88 
89   Moe::Dataspace_static *fb = new Moe::Dataspace_static((void*)vaddr, map_size,
90                                                         L4Re::Dataspace::F::RW | L4Re::Dataspace::F::Bufferable);
91 
92   _screen_info.width = vbi->x_resolution;
93   _screen_info.height = vbi->y_resolution;
94   _screen_info.flags = L4Re::Video::Goos::F_auto_refresh;
95   _screen_info.pixel_info = L4Re::Video::Pixel_info(vbi);
96 
97   _view_info.buffer_offset = base_offset;
98   _view_info.bytes_per_line = vbi->bytes_per_scanline;
99 
100   init_infos();
101 
102   _fb_ds = L4::cap_cast<L4Re::Dataspace>(object_pool.cap_alloc()->alloc(fb));
103 
104   object_pool.cap_alloc()->alloc(this);
105   root_name_space()->register_obj("vesa", 0, this);
106 
107   L4::cout << "  VESAFB: " << obj_cap() << _fb_ds
108     << " @" << (void*)(unsigned long)vbi->phys_base
109     << " (size=" << L4::hex << 64*1024*vbe->total_memory << ")\n" << L4::dec;
110 
111 }
112 
113