Decoding net: Fail on region resolution with non contiuous domain for address
[barrelfish] / usr / skb / programs / decoding_net.pl
1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 % Copyright (c) 2017, ETH Zurich.
3 % All rights reserved.
4 %
5 % This file is distributed under the terms in the attached LICENSE file.
6 % If you do not find this file, copies can be found by writing to:
7 % ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich.
8 % Attn: Systems Group.
9 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10
11 :- module(decoding_net).
12 :- export load_net/1.
13 :- export decodes_to/2.
14 :- export resolve/2.
15 :- export node/2.
16
17 :- dynamic node/2.
18
19 :- export struct(node(id:node_id,spec:node_spec)).
20 :- export struct(node_id(name,namespace)).
21 :- export struct(node_spec(type,accept,translate)).
22 :- local struct(map(src_block,dest_node,dest_base)).
23 :- local struct(block(base,limit)).
24
25 :- export struct(name(node_id:node_id,address)).
26 :- export struct(region(node_id:node_id,base,size)).
27
28 :- lib(ic).
29
30 :- set_flag(syntax_option,based_bignums).
31 :- set_flag(syntax_option,iso_base_prefix).
32
33 %% Load a precompiled decoding net
34 load_net(File) :-
35     ensure_loaded(File).
36
37 %% Convert from regions to names
38 to_name(Region,Name) :-
39     region{
40         node_id:Id,
41         base:Base,
42         size:Size
43     } = Region,
44     Addr #>= Base,
45     Addr #< Base + Size,
46     Name = name{
47         node_id:Id,
48         address:Addr
49     }.
50
51 %% Convert from names to regions
52 to_region(Name,Region) :-
53     name{
54         node_id:Id,
55         address:Addr
56     } = Name,
57     get_bounds(Addr,Min,Max),
58     Size is Max - Min + 1,
59     ( get_domain_size(Addr,Size) ->
60             Region = region{
61             node_id:Id,
62             base:Min,
63             size:Size
64         }
65     ;
66         writeln(stderr,"Name conversion to region failed: Non continuous domain for address"),
67         fail
68     ).
69
70 %% Address range in block
71 block_range(Block,Range) :-
72     block{
73         base:Base,
74         limit:Limit
75     } = Block,
76     Range = Base..Limit.
77
78 maps_to_name([Map|_],Addr,Name) :-
79         map{
80         src_block:SrcBlock,
81         dest_node:Dest,
82         dest_base:DestBase
83     } = Map,
84     name{
85         node_id:Dest,
86         address:DestAddr
87     } = Name,
88     block_range(SrcBlock,Range),
89     Addr :: Range,
90     block{base:SrcBase} = SrcBlock,
91     DestAddr #= Addr - SrcBase + DestBase.
92
93 maps_to_name([_|Maps],Addr,Name) :-
94     maps_to_name(Maps,Addr,Name).    
95
96 translate(NodeSpec,Addr,Name) :-
97     node_spec{translate:Translate} = NodeSpec,
98     maps_to_name(Translate,Addr,Name).
99
100 accept(NodeSpec,Addr) :-
101     node_spec{accept:Accept} = NodeSpec,
102     (
103         foreach(Block,Accept),
104         fromto([],Prev,Next,Ranges)
105     do
106         block_range(Block,Range),
107         Next = [Range|Prev]
108     ),
109     Addr :: Ranges.
110
111 accepted_name(Name) :-
112     name{
113         node_id:NodeId,
114         address:Addr
115     } = Name,
116     node{
117         id:NodeId,
118         spec:NodeSpec
119     },
120     accept(NodeSpec,Addr).
121
122 decode_step(SrcName,DestName) :-
123     name{
124         node_id:NodeId,
125         address:Addr
126     } = SrcName,
127     node{
128         id:NodeId,
129         spec:NodeSpec
130     },
131     translate(NodeSpec,Addr,DestName).
132
133 % Reflexive, transitive closure of decode_step
134 decodes_to(SrcName,DestName) :-
135     SrcName = DestName.
136
137 decodes_to(SrcName,DestName) :-
138     decode_step(SrcName,Name),
139     decodes_to(Name,DestName).
140
141 resolve(SrcName,DestName) :-
142     name{} = SrcName,
143     name{} = DestName,
144     decodes_to(SrcName,DestName),
145     accepted_name(DestName).
146
147 resolve(SrcRegion,DestRegion) :-
148     to_name(SrcRegion,SrcName),
149     to_name(DestRegion,DestName),
150     resolve(SrcName,DestName),
151     to_region(SrcName,SrcRegion),
152     to_region(DestName,DestRegion).
153