summaryrefslogtreecommitdiffstats
path: root/src/ssx/occhw/occhw_irq_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssx/occhw/occhw_irq_init.c')
-rw-r--r--src/ssx/occhw/occhw_irq_init.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/src/ssx/occhw/occhw_irq_init.c b/src/ssx/occhw/occhw_irq_init.c
new file mode 100644
index 0000000..da10cda
--- /dev/null
+++ b/src/ssx/occhw/occhw_irq_init.c
@@ -0,0 +1,180 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ssx/occhw/occhw_irq_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file occhw_irq_init.c
+/// \brief OCCHW IRQ initialization code for SSX
+///
+/// The entry points in this file are initialization rotines that could be
+/// eliminated/deallocated by the application to free up storage if they are
+/// no longer needed after initialization.
+
+#include "ssx.h"
+
+/// Define the polarity and trigger condition for an interrupt.
+///
+/// It is up to the application to take care of any side effects that may
+/// occur from programming or reprogramming the interrupt controller. For
+/// example, changing edge/level sensitivity or active level may set or clear
+/// interrupt status in the controller.
+///
+/// Note that SSX allows this API to be called from any context, and changes
+/// to the interrupt controller are made from an SSX_CRITICAL critical
+/// section.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_ARGUMENT_IRQ_SETUP One or more arguments are invalid,
+/// including an invalid \a irq, or invalid \a polarity or \a trigger parameters.
+
+int
+ssx_irq_setup(SsxIrqId irq,
+ int polarity,
+ int trigger)
+{
+ SsxMachineContext ctx;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(!OCCHW_IRQ_VALID(irq) ||
+ !OCCHW_IRQ_OWNED(irq) ||
+ !((polarity == SSX_IRQ_POLARITY_ACTIVE_HIGH) ||
+ (polarity == SSX_IRQ_POLARITY_ACTIVE_LOW)) ||
+ !((trigger == SSX_IRQ_TRIGGER_LEVEL_SENSITIVE) ||
+ (trigger == SSX_IRQ_TRIGGER_EDGE_SENSITIVE)),
+ SSX_INVALID_ARGUMENT_IRQ_SETUP);
+ }
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ if (polarity == SSX_IRQ_POLARITY_ACTIVE_HIGH) {
+ out32(OCCHW_OIEPR_OR(irq), OCCHW_IRQ_MASK32(irq));
+ } else {
+ out32(OCCHW_OIEPR_CLR(irq), OCCHW_IRQ_MASK32(irq));
+ }
+
+ if (trigger == SSX_IRQ_TRIGGER_EDGE_SENSITIVE) {
+ out32(OCCHW_OITR_OR(irq), OCCHW_IRQ_MASK32(irq));
+ } else {
+ out32(OCCHW_OITR_CLR(irq), OCCHW_IRQ_MASK32(irq));
+ }
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
+
+
+/// (Re)define the IRQ handler and priority for an interrupt.
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// Note that SSX allows this API to be called from any context, and changes
+/// to the interrupt controller are made from an SSX_CRITICAL critical
+/// section.
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_ARGUMENT_IRQ_HANDLER One or more arguments are
+/// invalid, including an invalid \a irq, a null (0) \a handler,
+/// or invalid \a priority.
+
+int
+ssx_irq_handler_set(SsxIrqId irq,
+ SsxIrqHandler handler,
+ void *arg,
+ int priority)
+{
+ SsxMachineContext ctx;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(!OCCHW_IRQ_VALID(irq) ||
+ !OCCHW_IRQ_OWNED(irq) ||
+ (handler == 0) ||
+ !((priority == SSX_NONCRITICAL) ||
+ (priority == SSX_CRITICAL)),
+ SSX_INVALID_ARGUMENT_IRQ_HANDLER);
+ }
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ //Regardless of priority, OIRRA & OIRRB will be cleared
+ out32(OCCHW_OIRRA_CLR(irq), OCCHW_IRQ_MASK32(irq));
+ out32(OCCHW_OIRRB_CLR(irq), OCCHW_IRQ_MASK32(irq));
+
+ //Critical priority needs a 1 in OIRRC
+ if (priority == SSX_CRITICAL) {
+ out32(OCCHW_OIRRC_OR(irq), OCCHW_IRQ_MASK32(irq));
+ } else {
+ out32(OCCHW_OIRRC_CLR(irq), OCCHW_IRQ_MASK32(irq));
+ }
+
+ __ppc405_irq_handlers[irq].handler = handler;
+ __ppc405_irq_handlers[irq].arg = arg;
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
+
+
+/// Set or clear interrupt debug mode explicitly.
+
+void
+ssx_irq_debug_set(SsxIrqId irq, int value)
+{
+ SsxMachineContext ctx;
+ //uint32_t ouder;
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ //TODO: port this over to using the OIRR instead of the OUDER
+ //ouder = in32(OCCHW_OUDER(irq));
+ if (value) {
+ //out32(OCCHW_OUDER(irq), ouder | OCCHW_IRQ_MASK32(irq));
+ } else {
+ //out32(OCCHW_OUDER(irq), ouder & ~OCCHW_IRQ_MASK32(irq));
+ }
+
+ ssx_critical_section_exit(&ctx);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
OpenPOWER on IntegriCloud