1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2% Copyright (c) 2009, 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, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9
10:- lib(ic).
11
12% current settings of link devices
13:- dynamic(setPir/2).
14
15% GSIs in use and their Pir
16:- dynamic(usedGsi/2).
17
18% current assignments
19:- dynamic(assignedGsi/3).
20
21findgsi(Pin, Addr, Gsi, Pir) :-
22        (
23            % lookup routing table to see if we have an entry
24            prt(Addr, Pin, PrtEntry)
25        ;
26            % if not, compute standard swizzle through bridge
27            Addr = addr(Bus, Device, _),
28            NewPin is (Device + Pin) mod 4,
29
30            % recurse, looking up mapping for the bridge itself
31            bridge(_, BridgeAddr, _, _, _, _, _, secondary(Bus)),
32            findgsi(NewPin, BridgeAddr, Gsi, Pir)
33        ),
34        ( % is this a fixed GSI, or a link device?
35            PrtEntry = gsi(Gsi),
36            Pir = fixedGsi
37        ;
38            PrtEntry = pir(Pir),
39            pir(Pir, Gsi)
40        ).
41
42assignirq(Pin, Addr, Pir, Gsi) :-
43        % determine usable GSIs for this device
44        findgsi(Pin, Addr, Gsi, Pir),
45        % don't change a previously-configured link device
46        (
47            Pir = fixedGsi
48        ;
49            setPir(Pir, _) -> setPir(Pir, Gsi)
50        ;
51            true
52        ),
53        % find all GSIs currently in use
54        findall(X, usedGsi(X,_), AllGsis),
55        % constrain GSIs not to overlap with the new GSI
56        ic:alldifferent([Gsi|AllGsis]),
57        indomain(Gsi),
58        % store settings for future reference
59        (
60            Pir = fixedGsi
61        ;
62            assert(setPir(Pir,Gsi))
63        ),
64        assert(usedGsi(Gsi,Pir)).
65
66assigndeviceirq(Addr) :-
67        device(_, Addr, _, _, _, _, _, Pin),
68        % ensure we have a sensible value for the Pin field
69        Pin >= 0 and Pin < 4,
70        ( % check for an exising allocation and return it if present
71            assignedGsi(Addr, Pin, Gsi),
72            usedGsi(Gsi, Pir)
73        ; % assign new IRQ
74            assignirq(Pin, Addr, Pir, Gsi),
75            assert(assignedGsi(Addr, Pin, Gsi))
76        ),
77        printf("%s %d\n", [Pir, Gsi]).
78