1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
//-----------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2014
// *! All Rights Reserved -- Property of IBM
// *! *** IBM Confidential ***
//-----------------------------------------------------------------------------
/// \file gpe_init.c
/// \brief PK initialization for GPE
///
/// The entry points in this routine are used during initialization. This
/// code space can be deallocated and reassigned after application
/// initialization if required.
#include "pk.h"
#include "ocb_register_addresses.h"
/// GPE environment initial setup.
///
/// This is setup common to all GPE HW Macro applications. This setup takes place
/// during boot, before main() is called.
void
__hwmacro_setup(void)
{
uint64_t oirrA;
uint64_t oirrB;
uint64_t oirrC;
uint64_t owned_actual;
uint64_t reverse_polarity;
//verify that this code is running on the correct GPE instance (one time check)
if((mfspr(SPRN_PIR) & PIR_PPE_INSTANCE_MASK) != APPCFG_OCC_INSTANCE_ID)
{
//APPCFG_OCC_INSTANCE_ID does not match actual instance ID!
PK_PANIC(OCCHW_INSTANCE_MISMATCH);
}
#if (APPCFG_OCC_INSTANCE_ID == OCCHW_IRQ_ROUTE_OWNER)
//If this instance is the owner of the interrupt routting registers
//then write the routing registers for all OCC interrupts.
//This instance must be the first instance to run within the OCC
//This will be done while all external interrupts are masked.
PKTRACE("Initializing External Interrupt Routing Registers");
out32(OCB_OIMR0_OR, 0xffffffff);
out32(OCB_OIMR1_OR, 0xffffffff);
out32(OCB_OIRR0A, (uint32_t)(g_ext_irqs_routeA >> 32));
out32(OCB_OIRR1A, (uint32_t)g_ext_irqs_routeA);
out32(OCB_OIRR0B, (uint32_t)(g_ext_irqs_routeB >> 32));
out32(OCB_OIRR1B, (uint32_t)g_ext_irqs_routeB);
out32(OCB_OIRR0C, (uint32_t)(g_ext_irqs_routeC >> 32));
out32(OCB_OIRR1C, (uint32_t)g_ext_irqs_routeC);
#endif
//Determine from the routing registers which irqs are owned by this instance
//NOTE: If a bit is not set in the routeA register, it is not owned by a GPE
oirrA = ((uint64_t)in32(OCB_OIRR0A)) << 32;
oirrA |= in32(OCB_OIRR1A);
oirrB = ((uint64_t)in32(OCB_OIRR0B)) << 32;
oirrB |= in32(OCB_OIRR1B);
oirrC = ((uint64_t)in32(OCB_OIRR0C)) << 32;
oirrC |= in32(OCB_OIRR1C);
//All interrupts routed to a GPE will have a bit set in routeA
owned_actual = oirrA;
//wittle it down by bits in the routeB register
#if APPCFG_OCC_INSTANCE_ID & 0x2
owned_actual &= oirrB;
#else
owned_actual &= ~oirrB;
#endif
//wittle it down further by bits in the routeC register
#if APPCFG_OCC_INSTANCE_ID & 0x1
owned_actual &= oirrC;
#else
owned_actual &= ~oirrC;
#endif
//Panic if we don't own the irqs we were expecting
//NOTE: we don't panic if we are given more IRQ's than expected
if((owned_actual & g_ext_irqs_owned) != g_ext_irqs_owned)
{
//IRQ's were not routed to us correctly.
PK_PANIC(OCC_IRQ_ROUTING_ERROR);
}
//Mask all external interrupts owned by this instance
//(even the ones given to us that we weren't expecting)
out32(OCB_OIMR0_OR, (uint32_t)(owned_actual >> 32));
out32(OCB_OIMR1_OR, (uint32_t)owned_actual);
//Set the interrupt type for all interrupts owned by this instance
out32(OCB_OITR0_CLR, (uint32_t)(g_ext_irqs_owned >> 32));
out32(OCB_OITR1_CLR, (uint32_t)g_ext_irqs_owned);
out32(OCB_OITR0_OR, (uint32_t)(g_ext_irqs_type >> 32));
out32(OCB_OITR1_OR, (uint32_t)g_ext_irqs_type);
//Set the interrupt polarity for all interrupts owned by this instance
out32(OCB_OIEPR0_CLR, (uint32_t)(g_ext_irqs_owned >> 32));
out32(OCB_OIEPR1_CLR, (uint32_t)g_ext_irqs_owned);
out32(OCB_OIEPR0_OR, (uint32_t)(g_ext_irqs_polarity >> 32));
out32(OCB_OIEPR1_OR, (uint32_t)g_ext_irqs_polarity);
//clear the status of all external interrupts owned by this instance
out32(OCB_OISR0_CLR, ((uint32_t)(g_ext_irqs_owned >> 32)));
out32(OCB_OISR1_CLR, ((uint32_t)g_ext_irqs_owned));
//set the status for interrupts that have reverse polarity
reverse_polarity = ~g_ext_irqs_polarity & g_ext_irqs_owned;
out32(OCB_OISR0_OR, ((uint32_t)(reverse_polarity >> 32)));
out32(OCB_OISR1_OR, ((uint32_t)reverse_polarity));
//Unmask the interrupts owned by this instance that are to be enabled by default
out32(OCB_OIMR0_CLR, (uint32_t)(g_ext_irqs_enable >> 32));
out32(OCB_OIMR1_CLR, (uint32_t)g_ext_irqs_enable);
//Wait for the last out32 operation to complete
sync();
}
|