vxKernel/include/vhex/arch/sh7305/intc.h

414 lines
10 KiB
C

#ifndef __VHEX_ARCH_SH7305_INTC__
# define __VHEX_ARCH_SH7305_INTC__
/* sh7305_intc_ipc - Interrupt Priority Controller
Some of the fields have been left unnamed because they correspond to SH7724
peripheral modules that are *very* unlikely to even exist in the SH7305, let
alone by of any use to us */
typedef volatile struct {
word_union(IPRA,
uint16_t TMU0_0 :4; /* TMU0 Channel 0 */
uint16_t TMU0_1 :4; /* TMU0 Channel 1 */
uint16_t TMU0_2 :4; /* TMU0 Channel 2 */
uint16_t :4;
);
pad(2);
word_union(IPRB,
uint16_t ADC : 4; /* A/D Converter */
uint16_t _1 : 4; /* Unknown (TODO) */
uint16_t _2 : 4; /* Unknown (TODO) */
uint16_t : 4;
);
pad(2);
word_union(IPRC,
uint16_t :4;
uint16_t :4;
uint16_t :4;
uint16_t SPU :4; /* SPU's DSP0 and DSP1 */
);
pad(2);
word_union(IPRD,
uint16_t :4;
uint16_t _MMCIF :4; /* SH7724: MultiMedia Card Interface */
uint16_t :4;
uint16_t :4;
);
pad(2);
word_union(IPRE,
uint16_t DMAC0A :4; /* Direct Memory Access Controller 0 */
uint16_t :4;
uint16_t ETMU3 :4; /* Extra TMU 3 */
uint16_t :4;
);
pad(2);
word_union(IPRF,
uint16_t KEYSC :4; /* Key Scan Interface */
uint16_t DMACOB :4; /* DMAC0 transfer/error info */
uint16_t USB0_1 :4; /* USB controller */
uint16_t CMT :4; /* Compare Match Timer */
);
pad(2);
word_union(IPRG,
uint16_t _SCIF0 :4; /* SH7724: SCIF0 transfer/error info */
uint16_t ETMU1 :4; /* Extra TMU 1 */
uint16_t ETMU2 :4; /* Extra TMU 2 */
uint16_t :4;
);
pad(2);
word_union(IPRH,
uint16_t _MSIOF0:4; /* SH7724: Sync SCIF channel 0 */
uint16_t _MSIOF1:4; /* SH7724: Sync SCIF channel 1 */
uint16_t _1 :4; /* Unknown (TODO) */
uint16_t _2 :4; /* Unknown (TODO) */
);
pad(2);
word_union(IPRI,
uint16_t ETMU4 :4; /* Extra TMU 4 */
uint16_t :4;
uint16_t _ :4; /* Unknown (TODO) */
uint16_t :4;
);
pad(2);
word_union(IPRJ,
uint16_t ETMU0 :4; /* Extra TMU 0 */
uint16_t _1 :4; /* Unknown (TODO) */
uint16_t FSI :4; /* FIFO-Buffered Serial Interface */
uint16_t _2 :4; /* Unknown (TODO) */
);
pad(2);
word_union(IPRK,
uint16_t RTC :4; /* Real-Time Clock */
uint16_t SDC :4; /* SD Card Controller */
uint16_t :4;
uint16_t :4;
);
pad(2);
word_union(IPRL,
uint16_t ETMU5 :4; /* Extra TMU 5 */
uint16_t _ :4; /* Unknown (TODO) */
uint16_t :4;
uint16_t :4;
);
} VPACKED(4) sh7305_intc_ipc_t;
/* sh7305_intc_masks_t - Interrupt mask management
Writing 1 to IMR masks interrupts; writing 1 to IMCRs clears the masks.
Writing 0 is ignored; reading from IMCRs yields undefined values */
typedef volatile struct {
byte_union(IMR0,
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t _0 : 1; /* Unknown (TODO) */
uint8_t _1 : 1; /* Unknown (TODO) */
uint8_t _2 : 1; /* Unknown (TODO) */
);
pad(3);
byte_union(IMR1,
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t DEI3 : 1; /* DMAC0 channel 3 */
uint8_t DEI2 : 1; /* DMAC0 channel 2 */
uint8_t DEI1 : 1; /* DMAC0 channel 1 */
uint8_t DEI0 : 1; /* DMAC0 channel 0 */
);
pad(3);
byte_union(IMR2,
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t _0 : 1; /* Unknown (TODO) */
uint8_t _1 : 1; /* Unknown (TODO) */
uint8_t ETUNI3 : 1; /* ETMU3 */
);
pad(3);
byte_union(IMR3,
uint8_t _0 : 1; /* Unknown (TODO) */
uint8_t _1 : 1; /* Unknown (TODO) */
uint8_t _2 : 1; /* Unknown (TODO) */
uint8_t _3 : 1; /* Unknown (TODO) */
uint8_t DSP0 : 1; /* SPU DSP1 */
uint8_t DSP1 : 1; /* SPU DSP0 */
uint8_t : 1;
uint8_t : 1;
);
pad(3);
byte_union(IMR4,
uint8_t : 1;
uint8_t TUNI0 : 1; /* TMU0 timer 0 */
uint8_t TUNI1 : 1; /* TMU0 timer 1 */
uint8_t TUNI2 : 1; /* TMU0 timer 2 */
uint8_t ADC : 1; /* A/D Converter */
uint8_t : 1;
uint8_t : 1;
uint8_t _ : 1; /* Unknown (TODO) */
);
pad(3);
byte_union(IMR5,
uint8_t KEYI : 1; /* KEYSC */
uint8_t DADERR : 1; /* DMAC0 Address error */
uint8_t DEI5 : 1; /* DMAC Channel 5 */
uint8_t DEI4 : 1; /* DMAC Channel 4 */
uint8_t : 1;
uint8_t ETMU2 : 1; /* ETMU 2 */
uint8_t ETMU1 : 1; /* ETMU 1 */
uint8_t _ : 1; /* Unknown (TODO) */
);
pad(3);
byte_union(IMR6,
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t ETUNI4 : 1; /* Extra Timer 4 */
uint8_t ETUNI0 : 1; /* Extra Timer 0 */
uint8_t : 1;
uint8_t _0 : 1; /* Unknown (TODO) */
uint8_t _1 : 1; /* Unknown (TODO) */
);
pad(3);
byte_union(IMR7,
uint8_t DTE0I : 1; /* I2C0 Transmit */
uint8_t WAITT0I : 1; /* I2C0 Wait */
uint8_t TACK0I : 1; /* I2C0 Non-ACK */
uint8_t AL0I : 1; /* I2C0 Arb. lost */
uint8_t TEINTE : 1; /* FCNTL Transfer end (SH7780)*/
uint8_t _0 : 1; /* Unknown (TODO) */
uint8_t _1 : 1; /* Unknown (TODO) */
uint8_t _2 : 1; /* Unknown (TODO) */
);
pad(3);
byte_union(IMR8,
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t _0 : 1; /* Unknown (TODO) */
uint8_t ETUNI5 : 1; /* Extra Timer 5 */
uint8_t FSI : 1; /* Fifo Serial Interface */
);
pad(3);
byte_union(IMR9,
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t CMT : 1; /* CMT */
uint8_t : 1;
uint8_t : 1;
uint8_t USI : 1; /* USB */
uint8_t : 1;
);
pad(3);
byte_union(IMR10,
uint8_t const : 1;
uint8_t const : 1;
uint8_t SDC : 1; /* SD Card */
uint8_t _ : 1; /* Unknown (TODO) */
uint8_t : 1;
uint8_t ATI : 1; /* RTC alarm */
uint8_t PRI : 1; /* RTC periodic interrupt */
uint8_t CUI : 1; /* RTC carry */
);
pad(3);
byte_union(IMR11,
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
uint8_t _ : 1; /* Unknown (TODO) */
);
pad(3);
byte_union(IMR12,
uint8_t : 1;
uint8_t : 1;
uint8_t _0 : 1; /* Unknown (TODO) */
uint8_t _1 : 1; /* Unknown (TODO) */
uint8_t _2 : 1; /* Unknown (TODO) */
uint8_t : 1;
uint8_t : 1;
uint8_t : 1;
);
} VPACKED(4) sh7305_intc_masks_t;
/* sh7305_intc_userimask_t - User Interrupt Mask
Sets the minimum required level for interrupts to be accepted.
WARNING: Writing to this register is only allowed when the upper bits of the
operand (ie. the new value of USERIMASK) are 0xa5; otherwise, the write is
ignored. To modify the value of this register, do not access the bit field
directly, backup the variable and modify it:
void set_user_imask(int new_level)
{
sh7305_intc_userimask_t mask = *(INTC._7305.USERIMASK);
mask._0xa5 = 0xa5;
mask.UIMASK = new_level & 0x0f;
*(INTC._7305.USERIMASK) = mask;
}
*/
typedef volatile lword_union(sh7305_intc_userimask_t,
uint32_t _0xa5 :8; /* Always set to 0xa5 before writing */
uint32_t :16;
uint32_t UIMASK :4; /* User Interrupt Mask Level */
uint32_t :4;
);
/* sh7305_icr0_t - Interrupt Control register 0
Configure the input signal detection mode. Note that this register differ a
bit from the SH7724 because the LVLMODE bit which allow us to select the
interrupt source retention seems removed in the SH7305 (emulator) */
typedef volatile word_union(sh7305_intc_icr0_t,
uint16_t NMIL : 1; /* NMI Input level */
uint16_t MAI : 1; /* NMI Interrupt Mask */
uint16_t : 4;
uint16_t NMIB : 1; /* NMI Block Mode */
uint16_t NMIE : 1; /* NMI Edge Select */
uint16_t _HIGH : 2; /* should be 1 */
uint16_t : 6;
);
/* sh7305_icr1_t - Interrupt Control register 1
Configure the detection mode for the external interrupt pins IRQ0 to IRQ3.
Note that the register differ from the SH7724 because we don't have the IRQ4,
IRQ5, IRQ6 and IRQ7. */
typedef volatile word_union(sh7305_intc_icr1_t,
uint16_t IRQ0S : 2; /* IRQ0 Sense select */
uint16_t IRQ1S : 2; /* IRQ1 Sense select */
uint16_t IRQ2S : 2; /* IRQ2 Sense select */
uint16_t IRQ3S : 2; /* IRQ3 Sense select */
uint16_t : 8;
);
/* sh7305_intpri00_t - Interrupt Priority register 0
Configure the interrupt level for the signal from pins IRQ0 to IRQ3. Note
that the register differ from the SH7724 because we don't have IRQ4 to IQ7.*/
typedef volatile lword_union(sh7305_intc_intpri00_t,
uint32_t IRQ0 : 4; /* IRQ0 priority level */
uint32_t IRQ1 : 4; /* IRQ0 priority level */
uint32_t IRQ2 : 4; /* IRQ0 priority level */
uint32_t IRQ3 : 4; /* IRQ0 priority level */
uint32_t : 16;
);
/* sh7305_intc_intreq00_t - Interrupt request 0 */
typedef volatile byte_union(sh7305_intc_intreq00_t,
uint8_t IRQ0 : 1; /* IRQ0 Interrupt Request */
uint8_t IRQ1 : 1; /* IRQ0 Interrupt Request */
uint8_t IRQ2 : 1; /* IRQ0 Interrupt Request */
uint8_t IRQ3 : 1; /* IRQ0 Interrupt Request */
uint8_t : 4;
);
/* sh7305_intc_intmsk00_t - Interrupt mask 0 */
typedef volatile byte_union(sh7305_intc_intmsk00_t,
uint8_t IRQ0 : 1; /* IRQ0 Interrupt Mask */
uint8_t IRQ1 : 1; /* IRQ0 Interrupt Mask */
uint8_t IRQ2 : 1; /* IRQ0 Interrupt Mask */
uint8_t IRQ3 : 1; /* IRQ0 Interrupt Mask */
uint8_t : 4;
);
/* sh7305_intc_intmskclr00_t - Interrupt mask clear 0 */
typedef volatile byte_union(sh7305_intc_intmskclr00_t,
uint8_t IRQ0 : 1; /* IRQ0 Interrupt Mask Clear */
uint8_t IRQ1 : 1; /* IRQ0 Interrupt Mask Clear */
uint8_t IRQ2 : 1; /* IRQ0 Interrupt Mask Clear */
uint8_t IRQ3 : 1; /* IRQ0 Interrupt Mask Clear */
uint8_t : 4;
);
/* sh7305_intc_nmifcr_t - NMI Flags control register
This register contains the NMI interrupt flags that can be cleared. Note that
the emultor set the NMIFL bit in NMIL. */
typedef volatile word_union(sh7305_intc_nmifcr_t,
uint16_t NMIL : 1; /* NMI Input Level */
uint16_t : 14;
uint16_t NMIFL : 1; /* NMI Interrupt Request */
);
/* sh7305_intc - the SH7305 interrupt controller */
struct sh7305_intc
{
/* Interrupt control register */
sh7305_intc_icr0_t *ICR0;
/* external IRQ pins configuration */
sh7305_intc_icr1_t *ICR1;
sh7305_intc_intpri00_t *INTPRI00;
sh7305_intc_intreq00_t *INTREQ00;
sh7305_intc_intmsk00_t *INTMSK00;
sh7305_intc_intmskclr00_t *INTMSKCLR00;
/* NMI configuration / flags */
sh7305_intc_nmifcr_t *NMIFCR;
/* Interrupt priority registers */
union {
sh7305_intc_ipc_t *_;
volatile uint16_t *IPR;
};
/* Interrupt mask & mask clear registers */
union {
sh7305_intc_masks_t *_MSK;
uint8_t *MSK;
};
union {
sh7305_intc_masks_t *_MSKCLR;
uint8_t *MSKCLR;
};
/* Other registers */
sh7305_intc_userimask_t *USERIMASK;
} VPACKED(4);
/* Provided by intc/intc.c */
extern struct sh7305_intc SH7305_INTC;
#endif /* __VHEX_ARCH_SH7305_INTC__ */