📄 board.c
字号:
/* -*-C-*-
*
* $Revision: 1.5 $
* $Author: kwelton $
* $Date: 2000/08/08 21:45:52 $
*
* board.c - Integrator-specific C code
*
* Copyright (c) ARM Limited 1998-2000
* All Rights Reserved.
*/
#include <windows.h>
#include <nkintr.h>
#include "mmu_h.h"
#include "win_plat.h"
/* Codes for hexadecimal characters */
static unsigned int alpha_codes[] =
{
0x007E, 0x080C, 0x01B6, 0x011E, 0x01CC, 0x01DA, 0x01FA, 0x2802,
0x01FE, 0x01CE, 0x01EE, 0x01F8, 0x0072, 0x01BC, 0x00F2, 0x00E2
};
/* Pre-MMU: Write the given pattern to the alpha LEDs */
void ARMSetAlpha(DWORD value)
{
volatile DWORD *AlphaBank = (DWORD *)INTEGRATOR_DBG_ALPHA;
/*
* Poll the scan in progress bit
*
* If the H/W is in the process of writing to the LED's then writing
* to the control register will screw things up
*/
while (*(volatile DWORD *)AlphaBank & 1)
;
*AlphaBank = value;
}
void ARMWriteAlpha(DWORD value)
{
ARMSetAlpha(alpha_codes[(value & 0x0F)] |
((alpha_codes[((value & 0xF0) >> 4)]) << 14));
}
/* Write the given pattern to the alpha LEDs */
void pHALir_SetAlpha(DWORD value)
{
volatile DWORD *AlphaBank =
(DWORD *)(VA_DBG_BASE + INTEGRATOR_DBG_ALPHA_OFFSET);
/*
* Poll the scan in progress bit
*/
while (*(volatile DWORD *)AlphaBank & 1)
;
*AlphaBank = value;
}
/* Convert the given value into the Alpha LED bit pattern */
void pHALr_WriteAlpha(DWORD value)
{
pHALir_SetAlpha(alpha_codes[(value & 0x0F)] |
((alpha_codes[((value & 0xF0) >> 4)]) << 14));
}
/* Pre-MMU: Initialise the LED(s) to given value - usually 0 */
int ARMSetLEDs(DWORD value)
{
volatile DWORD *LedBank = (DWORD *)LED_BANK;
/*
* Poll the scan in progress bit
*/
while (*(volatile DWORD *)INTEGRATOR_DBG_ALPHA & 1)
;
*LedBank = value;
/* Return the number of LEDs in the system */
return (uHAL_NUM_OF_LEDS);
}
/* Set the state of the specified LED */
DWORD pHALr_SetLEDs(DWORD value)
{
DWORD mask = 0;
DWORD VAOffset = (VA_DBG_BASE - INTEGRATOR_DBG_BASE);
volatile DWORD *LedBank = (DWORD *)(VAOffset + LED_BANK);
volatile DWORD *LedActive = (DWORD *)(VAOffset + INTEGRATOR_DBG_ALPHA);
#ifdef OldCode
if (value & 1)
mask |= GREEN_LED;
if (value & 2)
mask |= YELLOW_LED;
if (value & 4)
mask |= RED_LED;
if (value & 8)
mask |= GREEN_LED_2;
#else /* OldCode */
mask |= (value & ALL_LEDS);
#endif /* OldCode */
/*
* Poll the scan in progress bit
*/
while (*LedActive & 1)
;
*LedBank = mask;
return (uHAL_NUM_OF_LEDS);
}
/*
* Update the register on the target which masks the irq passed to the CPU.
* This routine is target-specific. Turn the interrupt source off.
*/
void pHALir_DisableIrq(DWORD irq)
{
LONG header_number;
volatile LONG *IRQBase;
volatile LONG *pHDRnum =
(volatile LONG *)(VA_HDR_BASE + INTEGRATOR_HDR_STAT_OFFSET);
header_number = *pHDRnum & 3;
IRQBase = (LONG *)(VA_IC_BASE + (header_number << 8));
IRQBase[(IRQ_ENABLE_CLEAR >> 2)] = (1 << irq);
}
/*
* Update the register on the target which masks the irq passed to the CPU.
* This routine is target-specific. Turn the interrupt source on.
*/
void pHALir_EnableIrq(DWORD irq)
{
LONG header_number;
volatile LONG *IRQBase;
volatile LONG *pHDRnum =
(volatile LONG *)(VA_HDR_BASE + INTEGRATOR_HDR_STAT_OFFSET);
header_number = *pHDRnum & 3;
IRQBase = (LONG *)(VA_IC_BASE + (header_number << 8));
IRQBase[(IRQ_ENABLE_SET >> 2)] = (1 << irq);
}
/*
* routine: uHALr_PCIHost()
*
* parameters: void
*
* description: This routine determines if the target is PCI Host.
*
* calls: none
*
* returns: FALSE if not PCI Host
*
*/
DWORD uHALr_PCIHost(void)
{
#if uHAL_PCI != 0
return (TRUE);
#else
return (FALSE);
#endif
}
/*
* Integrator Timer register definitions.
*
* Integrator has 2 fixed rate timers.
*/
typedef struct TimerStruct
{
unsigned short TimerLoad;
unsigned char pad0[2];
unsigned short TimerValue;
unsigned char pad1[2];
unsigned char TimerControl;
unsigned char pad2[3];
unsigned char TimerClear;
} TimerStruct_t;
TimerStruct_t *TimerBase[] =
{
0,
(TimerStruct_t *)(VA_CT_BASE + TIMER1_OFFSET),
(TimerStruct_t *)(VA_CT_BASE + TIMER2_OFFSET)
};
#ifdef OldCode
TimerStruct_t *PreMMU_TimerBase[] =
{
0,
(TimerStruct_t *)INTEGRATOR_TIMER1_BASE,
(TimerStruct_t *)INTEGRATOR_TIMER2_BASE
};
#endif /* def OldCode */
DWORD TimerInterrupts[] = TIMER_VECTORS;
/* Enum to describe timer: free, one-shot, on-going interval or locked-out */
enum uHALe_TimerState
{
T_FREE,
T_ONESHOT,
T_INTERVAL,
T_LOCKED
};
typedef struct uHALis_Timer
{
DWORD irq; /* IRQ number */
enum uHALe_TimerState state;
DWORD period; /* Period between triggers */
const BYTE *name; /* Debug, owner id */
struct uHALis_Timer *next;
/* Flag set if HW supports interval timers */
DWORD hw_interval:1;
} SoftTimer_t;
struct uHALis_Timer uHALiv_TimerStatus[MAX_TIMER + 1];
#define CLOCK_DIV_256 0x08
#define CLOCK_DIV_16 0x04
#define CLOCK_ENABLE 0x80
#define CLOCK_PERIODIC 0x40
void pHALir_ClearTimerInterrupt(DWORD timer)
{
volatile TimerStruct_t *Timer = TimerBase[timer];
/* clear the interrupt (if any) */
Timer->TimerClear = 1;
}
/* This routine stops the specified timer hardware. */
void uHALir_DisableTimer(DWORD timer)
{
volatile TimerStruct_t *Timer = TimerBase[timer];
struct uHALis_Timer *action;
/* Clear control register to disable timer */
Timer->TimerControl = 0;
/* clear the interrupt (if any) */
Timer->TimerClear = 1;
action = &uHALiv_TimerStatus[timer];
action->state = T_FREE;
}
/*
* This routine stores the interval for the given timer. NOTE: The actual
* timer count is not altered.
*
* Returns: -1 if timer is out of range
* OK otherwise
*/
DWORD uHALr_SetTimerInterval(DWORD timer, DWORD interval)
{
struct uHALis_Timer *action;
if (timer == 0 || timer > MAX_TIMER)
return 0;
if (interval > MAX_PERIOD)
return 0;
action = &uHALiv_TimerStatus[timer];
action->period = interval;
/*
* Force a H/W interval timer to be re-enabled next
* time it goes off so that it picks up this change.
*/
action->hw_interval = 0;
return (interval);
}
/*
* Routine to initialise install requested timer. Stops the timer.
*/
DWORD uHALir_InitTimer(DWORD timer, const BYTE *devname)
{
struct uHALis_Timer *action;
if (timer == 0 || timer > MAX_TIMER)
return 0;
uHALir_DisableTimer(timer);
action = &uHALiv_TimerStatus[timer];
action->state = T_INTERVAL; /* Default to interval timer */
action->name = devname;
action->irq = TimerInterrupts[timer]; /* IRQ number */
action->next = 0;
action->hw_interval = 0;
pHALir_DisableIrq(action->irq);
return timer;
}
/* Start-up routine to initialise the timers to a known state */
void uHALr_InitTimers(void)
{
DWORD i;
for (i = 1; i <= MAX_TIMER; i++)
{
uHALir_DisableTimer(i);
/* Default time period is 25 mS */
uHALr_SetTimerInterval(i, mSEC_1);
}
}
DWORD uHALr_RequestTimer(DWORD timer, const BYTE *devname)
{
if (uHALiv_TimerStatus[timer].state != T_FREE)
return 0;
return (uHALir_InitTimer(timer, devname));
}
/* This routine starts the specified timer hardware. */
void pHALr_EnableTimer(DWORD timer)
{
SoftTimer_t *action = &uHALiv_TimerStatus[timer];
volatile TimerStruct_t *Timer = TimerBase[timer];
DWORD ticks;
BYTE control = 0;
/* clear the interrupt (if any) */
Timer->TimerClear = 1;
/*
* Period is in usec.
* Calculate the number of ticks required.
*/
ticks = action->period * TICKS_PER_uSEC;
if (ticks >= 0x100000)
{
ticks >>= 8; /* Divide by 256 */
control = CLOCK_DIV_256;
}
else if (ticks >= 0x10000)
{
ticks >>= 4; /* Divide by 16 */
control = CLOCK_DIV_16;
}
control |= CLOCK_ENABLE;
/* set its count */
Timer->TimerLoad = (unsigned short)ticks;
if (action->state == T_INTERVAL)
{
/* H/W supports interval timer operation */
action->hw_interval = 1;
control |= CLOCK_PERIODIC;
}
Timer->TimerControl = control;
pHALir_EnableIrq(action->irq);
}
// Routine which calculates number of mSeconds left before OS_TIMER expires
DWORD HAL_mSecsLeft(void)
{
SoftTimer_t *action = &uHALiv_TimerStatus[OS_TIMER];
volatile TimerStruct_t *Timer = TimerBase[OS_TIMER];
DWORD ticks, count;
// Period is in usec. Calculate the number of ticks required.
ticks = action->period * TICKS_PER_uSEC;
// Read the count and scale up if required
count = Timer->TimerValue;
if (ticks >= 0x100000)
count <<= 8; /* Divided by 256 */
else if (ticks >= 0x10000)
count <<= 4; /* Divided by 16 */
// mS gone = start - count (converted from ticks)
return (ticks - count) / (TICKS_PER_uSEC * mSEC_1);
}
// Routine which calculates number of uSeconds left before OS_TIMER expires
DWORD HAL_uSecsLeft(void)
{
SoftTimer_t *action = &uHALiv_TimerStatus[OS_TIMER];
volatile TimerStruct_t *Timer = TimerBase[OS_TIMER];
DWORD ticks, count;
// Period is in usec. Calculate the number of ticks required.
ticks = action->period * TICKS_PER_uSEC;
// Read the count and scale up if required
count = Timer->TimerValue;
if (ticks >= 0x100000)
count <<= 8; /* Divided by 256 */
else if (ticks >= 0x10000)
count <<= 4; /* Divided by 16 */
// uS gone = start - count (converted from ticks)
return ((ticks - count) / TICKS_PER_uSEC);
}
/* EOF board.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -