Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2243 → Rev 2245

/branches/arm/kernel/arch/arm32/include/drivers/gxemul.h
41,6 → 41,18
void gxemul_kbd_release(void);
void gxemul_kbd_grab(void);
 
#define GXEMUL_IRQC_MAX_IRQ 8
inline uint32_t gxemul_irqc_get_sources(void);
inline void gxemul_irqc_mask(uint32_t irq);
inline void gxemul_irqc_unmask(uint32_t irq);
 
#define GXEMUL_TIMER_FREQ 2
void gxemul_timer_irq_init(void);
void gxemul_timer_start(uint32_t frequency);
 
 
 
#endif
 
/** @}
/branches/arm/kernel/arch/arm32/src/exception.c
38,8 → 38,8
#include <arch/memstr.h>
#include <arch/regutils.h>
#include <interrupt.h>
#include <arch/drivers/gxemul.h>
 
 
#define PREFETCH_OFFSET 0x8
#define BRANCH_OPCODE 0xea000000
#define LDR_OPCODE 0xe59ff000
47,21 → 47,7
#define EXC_VECTORS_SIZE 0x20
#define EXC_VECTORS 0x8
 
/* GXEmul interrupt controller macros
TODO might go to drivers/ together with servicing functions
*/
/* IRQ Controller device is added in a special premium gxemul
* edition at www.ms.mff.cuni.cz/~stepp3am/mygxemul-0.4.4.1.tar.gz
* :)
*/
#define IRQ_CONTROLLER_CAUSE 0x0000000016000000
#define IRQ_CONTROLLER_MAX_IRQ 8
 
/* IRQs */
#define CONSOLE_IRQ 2
#define TIMER_IRQ 4
 
 
#define SAVE_REGS_TO_STACK \
asm("stmfd sp!, {r0-r12, sp, lr}"); \
asm("mrs r14, spsr"); \
157,15 → 143,22
*/
static void irq_exception(int exc_no, istate_t* istate)
{
/* TODO this will call interrupt dispatching routine
*
*/
 
uint32_t sources = *(uint32_t*) IRQ_CONTROLLER_CAUSE;
uint32_t sources = gxemul_irqc_get_sources();
int i = 0;
int noirq = 1;
for (; i < IRQ_CONTROLLER_MAX_IRQ; i++) {
for (; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
aux_printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, i);
}
}
}
/* TODO remove after testing the above code
noirq = 0;
if (i == CONSOLE_IRQ) {
char readchar = *(char*)0x10000000;
179,7 → 172,7
}
else if (i == TIMER_IRQ) {
aux_printf("\n.\n");
/* acknowledge */
//acknowledge
*(uint32_t*)0x15000110 = 0;
}
}
186,7 → 179,7
}
 
if (noirq)
aux_puts("IRQ exception without source\n");
aux_puts("IRQ exception without source\n");*/
}
 
/** Fills exception vectors with appropriate exception handlers.
215,9 → 208,15
(unsigned*)EXC_FIQ_VEC);
}
 
/** Registers exceptions and their handlers to kernel exception dispatcher. */
/** Initializes exception handling.
*
* Installs low-level exception handlers and then registers
* exceptions and their handlers to kernel exception dispatcher.
*/
void exception_init(void)
{
install_exception_handlers();
exc_register(EXC_IRQ, "interrupt", (iroutine) irq_exception);
/* TODO add next */
}
232,6 → 231,10
);
asm("ldr sp, =irq_stack");
current_status_reg_control_write( cspr);
/* TODO if you want to test other exceptions than IRQ,
make stack analogous to irq_stack (in start.S),
and then set stack pointer here */
}
 
/** @}
/branches/arm/kernel/arch/arm32/src/arm32.c
42,6 → 42,8
#include "aux_print/printf.h"
#include <print.h>
#include <config.h>
#include <interrupt.h>
 
bootinfo_t bootinfo;
 
void arch_pre_main(void)
59,17 → 61,8
// aux_printf("%L, %d\n", bootinfo.tasks[i].addr, bootinfo.tasks[i].size);
}
 
/* TODO this code just setups irq testing bed
*/
/* TODO this code just setups irq testing bed */
setup_exception_stacks();
exception_init();
install_exception_handlers();
interrupts_enable();
/* activate timer interrupts */
*(uint32_t*)0x15000100 = 1;
 
while(1) ;
 
}
 
#include <ddi/irq.h>
76,6 → 69,12
void arch_pre_mm_init(void)
{
aux_printf("arch_pre_mm_init\n");
 
/* It is not assumed by default */
interrupts_disable();
/* Initialize dispatch table */
exception_init();
 
}
83,10 → 82,13
void arch_post_mm_init(void)
{
aux_printf("arch_post_mm_init\n");
// irq_init(8, 8); /// needs malloc ... so after mm init
// console_init(device_assign_devno()); // need hash table of irq ... so after irq_init
interrupt_init(); // needs malloc ... so after mm init
console_init(device_assign_devno()); // need hash table of irq ... so after irq_init
/* TODO */
 
interrupts_enable();
while(1);
}
 
void arch_post_cpu_init(void)
/branches/arm/kernel/arch/arm32/src/interrupt.c
1,5 → 1,5
/*
* Copyright (c) 2007 Petr Stepan, Michal Kebrt
* Copyright (c) 2007 Petr Stepan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
34,12 → 34,13
 
#include <arch/asm.h>
#include <arch/regutils.h>
#include <ddi/irq.h>
#include <arch/drivers/gxemul.h>
#include <interrupt.h>
 
#define IRQ_COUNT 8
 
#define IRQ_COUNT 8
 
 
/** Disable interrupts.
*
* @return Old interrupt priority level.
85,9 → 86,17
return current_status_reg_read();
}
 
void interrupt_init(void) {
/** Initialize basic tables for exception dispatching
* and starts the timer.
*/
void interrupt_init(void)
{
irq_init(IRQ_COUNT, IRQ_COUNT);
 
gxemul_timer_irq_init();
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
 
/** @}
*/
/branches/arm/kernel/arch/arm32/src/drivers/gxemul.c
1,5 → 1,5
/*
* Copyright (c) 2005-2007 Ondrej Palkovsky, Michal Kebrt
* Copyright (c) 2005-2007 Ondrej Palkovsky, Michal Kebrt, Petr Stepan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
39,14 → 39,25
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <print.h>
#include <ddi/device.h>
 
/** Address of devices. */
#define GXEMUL_VIDEORAM 0x10000000
#define GXEMUL_KBD_ADDRESS 0x10000000
#define GXEMUL_KBD_IRQ 0
#define GXEMUL_RTC 0x15000000
#define GXEMUL_RTC_FREQ 0x15000100
#define GXEMUL_RTC_ACK 0x15000110
#define GXEMUL_IRQC 0x16000000
#define GXEMUL_IRQC_MASK 0x16000004
#define GXEMUL_IRQC_UNMASK 0x16000008
 
/** IRQs */
#define GXEMUL_KBD_IRQ 2
#define GXEMUL_TIMER_IRQ 4
 
static chardev_t console;
static irq_t gxemul_irq;
static irq_t gxemul_timer_irq;
 
static void gxemul_write(chardev_t *dev, const char ch);
static void gxemul_enable(chardev_t *dev);
70,6 → 81,7
void gxemul_enable(chardev_t *dev)
{
// cp0_unmask_int(GXEMUL_KBD_IRQ);
gxemul_irqc_unmask(GXEMUL_KBD_IRQ);
}
 
/* Called from getc(). */
76,6 → 88,7
void gxemul_disable(chardev_t *dev)
{
// cp0_mask_int(GXEMUL_KBD_IRQ);
gxemul_irqc_mask(GXEMUL_KBD_IRQ);
}
 
/** Read character using polling, assume interrupts disabled */
108,7 → 121,8
ch = '\n';
if (ch == 0x7f)
ch = '\b';
chardev_push_character(&console, ch);
//chardev_push_character(&console, ch);
printf("%c", ch);
}
}
 
137,7 → 151,7
}
 
 
/* Return console object representing msim console */
/** Return console object representing msim console */
void gxemul_console(devno_t devno)
{
chardev_initialize("msim_console", &console, &gxemul_ops);
152,6 → 166,7
irq_register(&gxemul_irq);
// cp0_unmask_int(GXEMUL_KBD_IRQ);
gxemul_irqc_unmask(GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.devno", NULL, devno);
159,5 → 174,87
sysinfo_set_item_val("kbd.address.virtual", NULL, GXEMUL_KBD_ADDRESS);
}
 
/** Return the mask of active interrupts. */
inline uint32_t gxemul_irqc_get_sources(void)
{
return *(uint32_t*) GXEMUL_IRQC;
}
 
/** Masks interrupt.
*
* @param irq interrupt number
*/
inline void gxemul_irqc_mask(uint32_t irq)
{
*(uint32_t*) GXEMUL_IRQC_MASK = irq;
}
 
/** Unmasks interrupt.
*
* @param irq interrupt number
*/
inline void gxemul_irqc_unmask(uint32_t irq)
{
*(uint32_t*) GXEMUL_IRQC_UNMASK = irq;
}
 
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency interrupts frequency (0 disables RTC)
*/
void gxemul_timer_start(uint32_t frequency)
{
*(uint32_t*) GXEMUL_RTC_FREQ = frequency;
}
 
static irq_ownership_t gxemul_timer_claim(void)
{
return IRQ_ACCEPT;
}
 
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...)
{
/* TODO time drifts ??
unsigned long drift;
 
drift = cp0_count_read() - nextcount;
while (drift > cp0_compare_value) {
drift -= cp0_compare_value;
CPU->missed_clock_ticks++;
}
nextcount = cp0_count_read() + cp0_compare_value - drift;
cp0_compare_write(nextcount);
*/
 
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
//clock();
puts(" ");
spinlock_lock(&irq->lock);
/* TODO what's that? *
if (virtual_timer_fnc != NULL)
virtual_timer_fnc();
*/
}
 
/**
* Initializes and registers timer interrupt handler.
*/
void gxemul_timer_irq_init()
{
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
irq_register(&gxemul_timer_irq);
}
 
 
/** @}
*/
/branches/arm/kernel/arch/arm32/src/start.S
56,7 → 56,7
 
bl arch_pre_main
 
# bl main_bsp
bl main_bsp
 
b halt