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_queries).
12:- export find_device_region/2.
13:- export find_memory_region/2.
14:- export find_shared_memory_region/3.
15
16:- export discover_core/1.
17:- export discover_device/1.
18
19:- export kernel_page_table/4.
20:- export driver_register_regions/3.
21:- export driver_interrupt_enum/2.
22
23:- use_module(decoding_net).
24
25
26%%%%%%%%%%%%%
27%% Queries %%
28%%%%%%%%%%%%%
29%% Address space queries
30find_device_region(SrcRegion,DestRegion) :-
31    region{node_id:DeviceId} = DestRegion,
32    node{
33        id:DeviceId,
34        type:device
35    },
36    resolve(SrcRegion,DestRegion).
37
38find_memory_region(SrcRegion,DestRegion) :-
39    region{node_id:MemoryId} = DestRegion,
40    node{
41        id:MemoryId,
42        type:memory
43    },
44    resolve(SrcRegion,DestRegion).
45
46find_shared_memory_region(SrcRegion,DestRegion,SharedRegion) :-
47    region{node_id:SharedId} = SharedRegion,
48    node{
49        id:SharedId,
50        type:memory
51    },
52    resolve(SrcRegion,SharedRegion),
53    resolve(DestRegion,SharedRegion).
54
55%%%%%%%%%%%%%%%%%%%%%%%%%%
56% Core/Device Management %
57%%%%%%%%%%%%%%%%%%%%%%%%%%
58discover_core(Core) :-
59    node{id:Id,type:core},
60    decodes_to(name{name:Core,namespace:[]},name{node_id:Id}).
61
62discover_device(Device) :-
63    node{name:Device,type:device}.
64
65kernel_page_table(CoreID,MemoryIds,DeviceIds,PageTable) :-
66    meta{
67        node_id:Core,
68        key:hw_id,
69        value:CoreID
70    },
71    (
72        param(Core),
73        foreach(Id,MemoryIds),
74        fromto([],Prev,Next,MemoryRecords)
75    do
76        (
77            find_memory_region(region{node_id:Core,namespace:[],base:Base,size:Size},region{name:Id})
78        ;
79            node_id{name:CoreName} = Core,
80            exitError("Can't find memory '%a' from Core '%a'",[Id,CoreName])
81        ),
82        Next = [pt_memory(Base,Size)|Prev]
83    ),
84    (
85        param(Core),
86        foreach(Id,DeviceIds),
87        fromto([],Prev,Next,DeviceRecords)
88    do
89        (
90            find_device_region(region{node_id:Core,namespace:[],base:Base,size:Size},region{name:Id})
91        ;
92            node_id{name:CoreName} = Core,
93            exitError("Can't find device '%a' from Core '%a'",[Id,CoreName])
94        ),
95        Next = [pt_device(Base,Size)|Prev]
96    ),
97    length(MemoryRecords,NumMemory),
98    length(DeviceRecords,NumDevices),
99    PageTable = page_table(NumMemory,NumDevices,MemoryRecords,DeviceRecords).
100
101driver_register_regions(CoreID,DeviceIds,Regions) :-
102    meta{
103        node_id:Core,
104        key:hw_id,
105        value:CoreID
106    },
107    (
108        param(Core),
109        foreach(Id,DeviceIds),
110        fromto([],Prev,Next,Rs)
111    do
112        find_device_region(region{node_id:Core,namespace:[],base:Addr,size:Size},region{name:Id}),
113        Next = [reg(Addr,Size)|Prev]
114    ),
115    reverse(Rs,Regions).
116
117driver_interrupt_enum(DeviceIds, Interrupts) :-
118    (
119        foreach(Id,DeviceIds),
120        fromto([],Prev,Next,Is)
121    do
122        NodeId = node_id{name:Id, namespace:['Int']},
123        enum_translate_range(NodeId, Base, Limit),
124        Next = [int(Base,Limit)|Prev]
125    ),
126
127    reverse(Is,Interrupts).
128