SKB: Adapt decoding net scripts to use struct notation
[barrelfish] / usr / skb / programs / decodingNet.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(decodingNet).
12 :- export loadnet/1.
13 :- export resolve/2.
14 :- export toRegion/2.
15 :- export node/2.
16
17 :- dynamic node/2.
18
19 :- export struct(node(id:nodeId,spec:nodeSpec)).
20 :- export struct(nodeId(name,namespace)).
21 :- export struct(nodeSpec(type,accept,translate)).
22 :- local struct(map(srcBlock,destNode,destBase)).
23 :- local struct(block(base,limit)).
24
25 :- export struct(name(nodeId:nodeId,address)).
26 :- export struct(region(nodeId:nodeId,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 loadnet(File) :- [File].
35
36 %% Address range in block
37 blockRange(Block,Range) :-
38     block{
39         base:Base,
40         limit:Limit
41     } = Block,
42     Range = Base..Limit.
43
44 %% Address ranges in block list
45 blockListRanges(Blocks,Ranges) :-
46     (
47         foreach(Block,Blocks),
48         fromto([],Prev,Next,Ranges)
49     do
50         blockRange(Block,Range),
51         Next = [Range|Prev]
52     ).
53     
54 %% Extract block ranges from map list
55 mapListRanges(Maps,Ranges) :-
56     (
57         foreach(map{srcBlock:Block},Maps),
58         fromto([],Prev,Next,Blocks)
59     do
60         Next = [Block|Prev]
61     ),
62     blockListRanges(Blocks,Ranges).
63
64 mapsToName(Map,Addr,Name) :-
65     map{
66         srcBlock:SrcBlock,
67         destNode:Dest,
68         destBase:DestBase
69     } = Map,
70     name{
71         nodeId:Dest,
72         address:DestAddr
73     } = Name,
74     blockRange(SrcBlock,Range),
75     Addr :: Range,
76     block{base:SrcBase} = SrcBlock,
77     DestAddr #= Addr - SrcBase + DestBase.
78
79 listMapsToName([M|Maps],Addr,Name) :-
80     mapsToName(M,Addr,Name);
81     listMapsToName(Maps,Addr,Name).    
82
83 translateMap(NodeSpec,Addr,Name) :-
84     nodeSpec{translate:Translate} = NodeSpec,
85     listMapsToName(Translate,Addr,Name).
86
87 translate(Node,Addr,Name) :-
88     translateMap(Node,Addr,Name).
89
90 accept(NodeSpec,Addr) :-
91     nodeSpec{accept:Accept} = NodeSpec,
92     blockListRanges(Accept,Ranges),
93     Addr :: Ranges.
94
95 acceptedName(Name) :-
96     name{
97         nodeId:NodeId,
98         address:Addr
99     } = Name,
100     node{
101         id:NodeId,
102         spec:NodeSpec
103     },
104     accept(NodeSpec,Addr).
105
106 decodeStep(SrcName,DestName) :-
107     name{
108         nodeId:NodeId,
109         address:Addr
110     } = SrcName,
111     node{
112         id:NodeId,
113         spec:NodeSpec
114     },
115     translate(NodeSpec,Addr,DestName).
116
117 decodesTo(SrcName,DestName) :-
118     SrcName = DestName.
119
120 decodesTo(SrcName,DestName) :-
121     decodeStep(SrcName,Name),
122     decodesTo(Name,DestName).
123
124 resolve(SrcName,DestName) :-
125     decodesTo(SrcName,DestName),
126     acceptedName(DestName).
127
128 toRegion(Name,Region) :-
129     name{
130         nodeId:Id,
131         address:Addr
132     } = Name,
133     get_min(Addr,Min),get_max(Addr,Max),
134     Size is Max - Min + 1,
135     Region = region{
136         nodeId:Id,
137         base:Min,
138         size:Size
139     }.
140