Subversion Repositories HelenOS

Rev

Rev 2340 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2340 Rev 2355
Line 43... Line 43...
43
#include <mm/page.h>
43
#include <mm/page.h>
44
#include <arch/machine.h>
44
#include <arch/machine.h>
45
#include <arch/debug/print.h>
45
#include <arch/debug/print.h>
46
 
46
 
47
 
47
 
48
/** Address of devices. */
48
/** Addresses of devices. */
49
#define GXEMUL_VIDEORAM            0x10000000
49
#define GXEMUL_VIDEORAM            0x10000000
50
#define GXEMUL_KBD                 0x10000000
50
#define GXEMUL_KBD                 0x10000000
51
#define GXEMUL_HALT_OFFSET         0x10
51
#define GXEMUL_HALT_OFFSET         0x10
52
#define GXEMUL_RTC                 0x15000000
52
#define GXEMUL_RTC                 0x15000000
53
#define GXEMUL_RTC_FREQ_OFFSET     0x100
53
#define GXEMUL_RTC_FREQ_OFFSET     0x100
Line 81... Line 81...
81
    .suspend = gxemul_disable,
81
    .suspend = gxemul_disable,
82
    .write = gxemul_write,
82
    .write = gxemul_write,
83
    .read = gxemul_do_read,
83
    .read = gxemul_do_read,
84
};
84
};
85
 
85
 
86
/** Return the mask of active interrupts. */
86
/** Returns the mask of active interrupts. */
87
static inline uint32_t gxemul_irqc_get_sources(void)
87
static inline uint32_t gxemul_irqc_get_sources(void)
88
{
88
{
89
    return *(uint32_t*) gxemul_hw_map.irqc;
89
    return *(uint32_t*) gxemul_hw_map.irqc;
90
}
90
}
91
 
91
 
Line 236... Line 236...
236
static irq_ownership_t gxemul_timer_claim(void)
236
static irq_ownership_t gxemul_timer_claim(void)
237
{
237
{
238
    return IRQ_ACCEPT;
238
    return IRQ_ACCEPT;
239
}
239
}
240
 
240
 
-
 
241
/** Timer interrupt handler.
-
 
242
 *
-
 
243
 * @param irq interrupt information
-
 
244
 */
241
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...)
245
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...)
242
{
246
{
243
    /* TODO time drifts ??
247
    /* TODO time drifts ??
244
    unsigned long drift;
248
    unsigned long drift;
245
 
249
 
Line 267... Line 271...
267
    if (virtual_timer_fnc != NULL)
271
    if (virtual_timer_fnc != NULL)
268
        virtual_timer_fnc();
272
        virtual_timer_fnc();
269
    */
273
    */
270
}
274
}
271
 
275
 
272
/**
-
 
273
 * Initializes and registers timer interrupt handler.
276
/** Initializes and registers timer interrupt handler.
274
 */
277
 */
275
static void gxemul_timer_irq_init()
278
static void gxemul_timer_irq_init()
276
{
279
{
277
    irq_initialize(&gxemul_timer_irq);
280
    irq_initialize(&gxemul_timer_irq);
278
    gxemul_timer_irq.devno = device_assign_devno();
281
    gxemul_timer_irq.devno = device_assign_devno();
Line 281... Line 284...
281
    gxemul_timer_irq.handler = gxemul_timer_irq_handler;
284
    gxemul_timer_irq.handler = gxemul_timer_irq_handler;
282
 
285
 
283
    irq_register(&gxemul_timer_irq);
286
    irq_register(&gxemul_timer_irq);
284
}
287
}
285
 
288
 
-
 
289
/** Starts timer.
-
 
290
 *
-
 
291
 * Initiates regular timer interrupts after initializing
-
 
292
 * corresponding interrupt handler.
-
 
293
 */
286
void machine_timer_irq_start()
294
void machine_timer_irq_start()
287
{
295
{
288
    gxemul_timer_irq_init();
296
    gxemul_timer_irq_init();
289
    gxemul_timer_start(GXEMUL_TIMER_FREQ);
297
    gxemul_timer_start(GXEMUL_TIMER_FREQ);
290
}
298
}
291
 
299
 
-
 
300
/** Returns the size of emulated memory.
-
 
301
 *
-
 
302
 * @return size in bytes
-
 
303
 */
292
size_t machine_get_memory_size(void)
304
size_t machine_get_memory_size(void)
293
{
305
{
294
    return  *((int*)(GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET));
306
    return  *((int*)(GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET));
295
}
307
}
296
 
308
 
Line 304... Line 316...
304
    }
316
    }
305
 
317
 
306
    *(addr) = ch;
318
    *(addr) = ch;
307
}
319
}
308
 
320
 
-
 
321
/** Stops gxemul. */
309
void machine_cpu_halt(void)
322
void machine_cpu_halt(void)
310
{
323
{
311
    char * addr = 0;
324
    char * addr = 0;
312
    if (!hw_map_init_called) {
325
    if (!hw_map_init_called) {
313
        addr = (char *) GXEMUL_KBD;
326
        addr = (char *) GXEMUL_KBD;
Line 316... Line 329...
316
    }
329
    }
317
   
330
   
318
    *(addr + GXEMUL_HALT_OFFSET) = '\0';
331
    *(addr + GXEMUL_HALT_OFFSET) = '\0';
319
}
332
}
320
 
333
 
-
 
334
/** Gxemul specific interrupt exception handler.
-
 
335
 *
-
 
336
 * Determines sources of the interrupt from interrupt controller and
-
 
337
 * calls high-level handlers for them.
-
 
338
 *
-
 
339
 * @param exc_no interrupt exception number
-
 
340
 * @param istate saved processor state
-
 
341
 */
321
void machine_irq_exception(int exc_no, istate_t *istate)
342
void machine_irq_exception(int exc_no, istate_t *istate)
322
{
343
{
323
    /* switch to Undefined mode */
-
 
324
    /*
-
 
325
    asm volatile(
-
 
326
        "stmfd sp!, {r0-r3}\n"
-
 
327
        "mov r1, sp\n"
-
 
328
        "mov r2, lr\n"
-
 
329
        "mrs r3, spsr\n"
-
 
330
        "mrs r0, cpsr\n"
-
 
331
        "bic r0, r0, #0x1f\n"
-
 
332
        "orr r0, r0, #0x1b\n"
-
 
333
        "msr cpsr_c, r0\n"
-
 
334
        "mov sp, r1\n"
-
 
335
        "mov lr, r2\n"
-
 
336
        "msr spsr, r3\n"
-
 
337
        "ldmfd sp!, {r0-r3}\n"
-
 
338
    );
-
 
339
    */
-
 
340
 
-
 
341
    uint32_t sources = gxemul_irqc_get_sources();
344
    uint32_t sources = gxemul_irqc_get_sources();
342
    int i = 0;
345
    int i = 0;
343
    for (; i < GXEMUL_IRQC_MAX_IRQ; i++) {
346
    for (; i < GXEMUL_IRQC_MAX_IRQ; i++) {
344
        if (sources & (1 << i)) {
347
        if (sources & (1 << i)) {
345
            irq_t *irq = irq_dispatch_and_lock(i);
348
            irq_t *irq = irq_dispatch_and_lock(i);
Line 351... Line 354...
351
                /* Spurious interrupt.*/
354
                /* Spurious interrupt.*/
352
                dprintf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, i);
355
                dprintf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, i);
353
            }
356
            }
354
        }
357
        }
355
    }
358
    }
356
    /* TODO remove after testing the above code
-
 
357
            noirq = 0;
-
 
358
            if (i == CONSOLE_IRQ) {
-
 
359
                char readchar = *(char*)0x10000000;
-
 
360
                if (readchar == 0) {
-
 
361
                    aux_puts("?");
-
 
362
                }
-
 
363
                else {
-
 
364
                    dprintf("%c", readchar);
-
 
365
                }
-
 
366
               
-
 
367
            }
-
 
368
            else if (i == TIMER_IRQ) {
-
 
369
                dprintf("\n.\n");
-
 
370
                //acknowledge
-
 
371
                *(uint32_t*)0x15000110 = 0;
-
 
372
            }
-
 
373
        }
-
 
374
    }
-
 
375
 
-
 
376
    if (noirq)
-
 
377
    aux_puts("IRQ exception without source\n");*/
-
 
378
}
359
}
379
 
360
 
380
 
361
 
381
/** @}
362
/** @}
382
 */
363
 */