]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/map_util-io.cpp
update
[l4.git] / kernel / fiasco / src / kern / ia32 / map_util-io.cpp
1 /*
2  * Fiasco-ia32
3  * Specific code for I/O port protection
4  */
5
6 IMPLEMENTATION[(ia32|amd64) & io]:
7
8 #include "l4_types.h"
9 #include "assert.h"
10 #include "space.h"
11 #include "io_space.h"
12
13 Mapdb*
14 io_mapdb_instance()
15 {
16   static const size_t io_page_sizes[] = 
17     {Io_space::Map_superpage_shift, 9, Io_space::Page_shift};
18   static Mapdb mapdb (sigma0_task,
19       Page_number::create(0x10000 >> io_page_sizes[0]), io_page_sizes, 3);
20
21   return &mapdb;
22 }
23
24 /** Map the IO port region described by "fp_from" of address space "from" 
25     into address space "to". IO ports can only be mapped idempotently, 
26     therefore there is no offset for fp_from and only those ports are mapped 
27     that lay in the intersection of fp_from and fp_to
28     @param from source address space
29     @param fp_from... IO flexpage descripton for IO space range
30         in source IO space      
31     @param to destination address space
32     @param fp_to... IO flexpage description for IO space range
33         in destination IO space
34     @return IPC error code that describes the status of the operation
35  */
36 L4_error
37 io_map(Space *from, L4_fpage const &fp_from,
38        Space *to, L4_fpage const &fp_to, L4_msg_item control)
39 {
40 /*   printf("io_map %u -> %u "
41  *          "snd %08x base %x size %x rcv %08x base %x size %x\n",
42  *          (unsigned)from->space(), (unsigned)to->space(),
43  *          fp_from.fpage, 
44  *          fp_from.iofp.iopage, fp_from.iofp.iosize,
45  *          fp_to.fpage, 
46  *          fp_to.iofp.iopage, fp_to.iofp.iosize);
47  *   kdb_ke("io_fpage_map 1");
48  */
49
50   typedef Map_traits<Io_space> Mt;
51   Mt::Addr rcv_pos = Mt::get_addr(fp_to);
52   Mt::Addr snd_pos = Mt::get_addr(fp_from);
53
54   Mt::Size rcv_size = Mt::Size::from_shift(fp_to.order());
55   Mt::Size snd_size = Mt::Size::from_shift(fp_from.order());
56
57   snd_pos = snd_pos.trunc(snd_size);
58   rcv_pos = rcv_pos.trunc(rcv_size);
59   Mt::constraint(snd_pos, snd_size, rcv_pos, rcv_size, Mt::Addr(0));
60
61   if (snd_size == 0)
62     return L4_error::None;
63
64   //assert(snd_pos < L4_fpage::Io_port_max);
65
66   unsigned long del_attribs, add_attribs;
67   Mt::attribs(control, fp_from, &del_attribs, &add_attribs);
68
69   return map (io_mapdb_instance(),
70               from->io_space(), from, snd_pos,
71               snd_size,
72               to->io_space(), to, snd_pos,
73               control.is_grant(), add_attribs, del_attribs,
74               (Io_space::Reap_list**)0);
75 }
76
77 /** Unmap IO mappings.
78     Unmap the region described by "fp" from the IO
79     space "space" and/or the IO spaces the mappings have been
80     mapped into. 
81     XXX not implemented yet
82     @param space address space that should be flushed
83     @param fp    IO flexpage descriptor of IO-space range that should
84                  be flushed
85     @param me_too If false, only flush recursive mappings.  If true, 
86                  additionally flush the region in the given address space.
87     @return true if successful
88 */
89 unsigned
90 io_fpage_unmap(Space *space, L4_fpage fp, L4_map_mask mask)
91 {
92   typedef Map_traits<Io_space> Mt;
93   Mt::Size size = Mt::Size::from_shift(fp.order());
94   Mt::Addr port = Mt::get_addr(fp);
95   port = port.trunc(size);
96
97   // Here we _would_ reset IOPL to 0 but this doesn't make much sense
98   // for only one thread since this thread may have forwarded the right
99   // to other threads too. Therefore we had to walk through any thread
100   // of this space.
101   //
102   // current()->regs()->eflags &= ~EFLAGS_IOPL;
103
104   return unmap(io_mapdb_instance(), space->io_space(), space,
105                port, size,
106                fp.rights(), mask, (Io_space::Reap_list**)0);
107 }
108
109 static inline
110 void
111 save_access_attribs (Mapdb* /*mapdb*/, const Mapdb::Frame& /*mapdb_frame*/,
112                      Mapping* /*mapping*/, Io_space* /*space*/, 
113                      unsigned /*page_rights*/, 
114                      Io_space::Addr /*virt*/, Io_space::Phys_addr /*phys*/,
115                      Io_space::Size /*size*/,
116                      bool /*me_too*/)
117 {}