This commit is contained in:
Jan Stoess 2010-07-14 12:07:01 +02:00
commit 4a249a0bd3
2 changed files with 57 additions and 44 deletions

View File

@ -169,11 +169,13 @@ void SECTION (".init") intctrl_t::init_arch()
void SECTION(".init") intctrl_t::init_cpu(int cpu) void SECTION(".init") intctrl_t::init_cpu(int cpu)
{ {
#ifdef CONFIG_SMP
ASSERT(cpu < 4); ASSERT(cpu < 4);
/* map IPIs */ /* map IPIs */
set_irq_routing(get_ipi_irq(cpu, 0), cpu); set_irq_routing(get_ipi_irq(cpu, 0), cpu);
enable(get_ipi_irq(cpu, 0)); enable(get_ipi_irq(cpu, 0));
#endif
} }
word_t intctrl_t::init_controllers() { word_t intctrl_t::init_controllers() {
@ -496,24 +498,29 @@ bool intctrl_t::unmask(word_t irq)
irq -= INT_LEVEL_UIC2_MIN ; irq -= INT_LEVEL_UIC2_MIN ;
intMask = 1 << (31 - irq) ; intMask = 1 << (31 - irq) ;
mtdcr(UIC2_SR, intMask); /* clear pending interrupts */ //Check if interrupt was already pending
mtdcr(UIC0_SR, uic2_dchain_mask); /* clear pending dchain */ if ((mfdcr(UIC2_SR) & intMask) > 0) {
mtdcr(UIC2_SR, intMask); /* clear pending interrupts */
mtdcr(UIC0_SR, uic2_dchain_mask); /* clear pending dchain */
return true;
} else {
/* /*
* enable the interrupt level * enable the interrupt level
* We must lock out interrupts to enable the hardware * We must lock out interrupts to enable the hardware
* as the handler may crush what we just did in UIC_ER. * as the handler may crush what we just did in UIC_ER.
*/ */
lock.lock(); /* lock interrupts */ lock.lock(); /* lock interrupts */
mtdcr(UIC2_ER, intMask | mfdcr(UIC2_ER)); mtdcr(UIC2_ER, intMask | mfdcr(UIC2_ER));
/* Enable dchain*/ /* Enable dchain*/
mtdcr(UIC0_ER, uic2_dchain_mask | mfdcr(UIC0_ER)); mtdcr(UIC0_ER, uic2_dchain_mask | mfdcr(UIC0_ER));
lock.unlock(); /* re-enable interrupts */
lock.unlock(); /* re-enable interrupts */
return false;
}
} }
else if (irq > INT_LEVEL_UIC0_MAX) /* For UIC1 */ else if (irq > INT_LEVEL_UIC0_MAX) /* For UIC1 */
#else #else
@ -522,45 +529,56 @@ bool intctrl_t::unmask(word_t irq)
{ {
irq -= INT_LEVEL_UIC1_MIN ; irq -= INT_LEVEL_UIC1_MIN ;
intMask = 1 << (31 - irq) ; intMask = 1 << (31 - irq) ;
mtdcr(UIC1_SR, intMask); /* clear pending interrupts */
mtdcr(UIC0_SR, uic1_dchain_mask); /* clear pending dchain */
/* //Check if interrupt was already pending
* enable the interrupt level if ((mfdcr(UIC1_SR) & intMask) > 0) {
* We must lock out interrupts to enable the hardware mtdcr(UIC1_SR, intMask); /* clear pending interrupts */
* as the handler may crush what we just did in UIC_ER. mtdcr(UIC0_SR, uic1_dchain_mask); /* clear pending dchain */
*/ return true;
} else {
lock.lock(); /* lock interrupts */ /*
* enable the interrupt level
* We must lock out interrupts to enable the hardware
* as the handler may crush what we just did in UIC_ER.
*/
mtdcr(UIC1_ER, intMask | mfdcr(UIC1_ER)); lock.lock(); /* lock interrupts */
/* Enable dchain*/ mtdcr(UIC1_ER, intMask | mfdcr(UIC1_ER));
mtdcr(UIC0_ER, uic1_dchain_mask | mfdcr(UIC0_ER));
lock.unlock(); /* re-enable interrupts */ /* Enable dchain*/
mtdcr(UIC0_ER, uic1_dchain_mask | mfdcr(UIC0_ER));
lock.unlock(); /* re-enable interrupts */
return false;
}
} }
else else
{ {
intMask = 1 << (31 - irq) ; intMask = 1 << (31 - irq) ;
mtdcr(UIC0_SR, intMask); /* clear pending interrupts */
/* //Check if interrupt was already pending
* enable the interrupt level if ((mfdcr(UIC0_SR) & intMask) > 0) {
* We must lock out interrupts to enable the hardware mtdcr(UIC0_SR, intMask); /* clear pending interrupts */
* as the handler may crush what we just did in UIC_ER. return true;
*/ } else {
lock.lock(); /* lock interrupts */ /*
* enable the interrupt level
* We must lock out interrupts to enable the hardware
* as the handler may crush what we just did in UIC_ER.
*/
mtdcr(UIC0_ER, intMask | mfdcr(UIC0_ER)); lock.lock(); /* lock interrupts */
lock.unlock(); /* re-enable interrupts */ mtdcr(UIC0_ER, intMask | mfdcr(UIC0_ER));
lock.unlock(); /* re-enable interrupts */
return false;
}
} }
return true;
} }
bool intctrl_t::is_masked(word_t irq) { bool intctrl_t::is_masked(word_t irq) {

View File

@ -158,8 +158,10 @@ public:
bool is_pending(word_t irq); bool is_pending(word_t irq);
void enable(word_t irq) void enable(word_t irq) {
{ unmask(irq); } if (unmask(irq))
::handle_interrupt(irq);
}
void disable(word_t irq) void disable(word_t irq)
{ mask(irq); } { mask(irq); }
@ -180,12 +182,6 @@ public:
*/ */
void handle_irq(word_t cpu); void handle_irq(word_t cpu);
//noncritical interrupt handler
void sysUicIntHandler(void);
//critical interrupt handler;
void sysUicCrtIntHandler(void);
/* map routine provided by glue */ /* map routine provided by glue */
void map(); void map();
@ -225,7 +221,6 @@ private:
return cpu * 8 + ipi; return cpu * 8 + ipi;
} }
//common interrupt handler, should not be called directly. //common interrupt handler, should not be called directly.
void sysUicIntHandlerCommon(bool intIsCritical);
void raise_irq(word_t irq); void raise_irq(word_t irq);
}; };