/SPARTAN/trunk/arch/ia64/include/interrupt.h |
---|
29,6 → 29,9 |
#ifndef __ia64_INTERRUPT_H__ |
#define __ia64_INTERRUPT_H__ |
#define INTERRUPT_TIMER 0 |
#define INTERRUPT_SPURIOUS 15 |
extern void external_interrupt(void); |
#endif |
/SPARTAN/trunk/arch/ia64/include/types.h |
---|
35,8 → 35,8 |
typedef unsigned char __u8; |
typedef unsigned short __u16; |
typedef unsigned long __u32; |
typedef long long __u64; |
typedef unsigned int __u32; |
typedef unsigned long __u64; |
typedef __u64 __address; |
/SPARTAN/trunk/arch/ia64/include/asm.h |
---|
92,9 → 92,22 |
__asm__ volatile ("mov cr.itm = %0\n" : : "r" (v)); |
} |
/** Read ITV (Interval Timer Vector) register. |
* |
* @return Current vector and mask bit. |
*/ |
static inline __u64 itv_read(void) |
{ |
__u64 v; |
__asm__ volatile ("mov %0 = cr.itv\n" : "=r" (v)); |
return v; |
} |
/** Write ITV (Interval Timer Vector) register. |
* |
* @param New vector and masked bit. |
* @param New vector and mask bit. |
*/ |
static inline void itv_write(__u64 v) |
{ |
/SPARTAN/trunk/arch/ia64/include/register.h |
---|
32,7 → 32,41 |
#include <arch/types.h> |
#define CR_IVR_MASK 0xf |
#define PSR_I_MASK 0x4000 |
/** External Interrupt Vector Register */ |
union cr_ivr { |
__u8 vector; |
__u64 value; |
}; |
typedef union cr_ivr cr_ivr_t; |
/** Task Priority Register */ |
union cr_tpr { |
struct { |
unsigned : 4; |
unsigned mic: 4; /**< Mask Interrupt Class. */ |
unsigned : 8; |
unsigned mmi: 1; /**< Mask Maskable Interrupts. */ |
} __attribute__ ((packed)); |
__u64 value; |
}; |
typedef union cr_tpr cr_tpr_t; |
/** Interval Timer Vector */ |
union cr_itv { |
struct { |
unsigned vector : 8; |
unsigned : 4; |
unsigned : 1; |
unsigned : 3; |
unsigned m : 1; /**< Mask. */ |
} __attribute__ ((packed)); |
__u64 value; |
}; |
typedef union cr_itv cr_itv_t; |
#endif |
/SPARTAN/trunk/arch/ia64/src/ia64.c |
---|
28,7 → 28,14 |
#include <arch.h> |
#include <arch/ski/ski.h> |
#include <arch/asm.h> |
#include <arch/register.h> |
#include <arch/barrier.h> |
#include <arch/interrupt.h> |
/** TODO: read ticks per second from firmware */ |
#define IT_DELTA 50000000 |
void arch_pre_mm_init(void) |
{ |
ski_init_console(); |
36,4 → 43,20 |
void arch_post_mm_init(void) |
{ |
cr_itv_t itv; |
/* initialize Interval Timer external interrupt vector */ |
itv.value = itv_read(); |
itv.vector = INTERRUPT_TIMER; |
itv.m = 0; |
itv_write(itv.value); |
srlz_d(); |
/* set Interval Timer Counter to zero */ |
itc_write(0); |
srlz_d(); |
/* generate first Interval Timer interrupt in IT_DELTA ticks */ |
itm_write(IT_DELTA); |
srlz_d(); |
} |
/SPARTAN/trunk/arch/ia64/src/interrupt.c |
---|
29,21 → 29,29 |
#include <arch/interrupt.h> |
#include <panic.h> |
#include <print.h> |
#include <arch/types.h> |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <arch/register.h> |
#include <arch.h> |
void external_interrupt(void) |
{ |
__u8 ivr; |
cr_ivr_t ivr; |
ivr.value = ivr_read(); |
srlz_d(); |
ivr = ivr_read() & CR_IVR_MASK; |
srlz_d(); |
switch(ivr) { |
switch(ivr.value) { |
case INTERRUPT_TIMER: |
panic("cpu%d: timer interrupt\n", CPU->id); |
break; |
case INTERRUPT_SPURIOUS: |
printf("cpu%d: spurious interrupt\n", CPU->id); |
break; |
default: |
panic("\nUnhandled External Interrupt Vector %d\n", ivr); |
panic("\nUnhandled External Interrupt Vector %d\n", ivr.vector); |
break; |
} |
} |