/trunk/kernel/arch/arm32/include/machine.h |
---|
File deleted |
/trunk/kernel/arch/arm32/include/debug/print.h |
---|
File deleted |
/trunk/kernel/arch/arm32/include/drivers/gxemul.h |
---|
38,41 → 38,33 |
#ifndef KERN_arm32_GXEMUL_H_ |
#define KERN_arm32_GXEMUL_H_ |
#include <console/chardev.h> |
/** Last interrupt number (beginning from 0) whose status is probed |
* from interrupt controller |
*/ |
#define GXEMUL_IRQC_MAX_IRQ 8 |
#define GXEMUL_KBD_IRQ 2 |
#define GXEMUL_TIMER_IRQ 4 |
/** Timer frequency */ |
#define GXEMUL_TIMER_FREQ 100 |
/** Struct containing mappings of gxemul HW devices into kernel part |
* of virtual address space. |
*/ |
typedef struct { |
uintptr_t videoram; |
uintptr_t kbd; |
uintptr_t rtc; |
uintptr_t rtc_freq; |
uintptr_t rtc_ack; |
uintptr_t irqc; |
uintptr_t irqc_mask; |
uintptr_t irqc_unmask; |
} gxemul_hw_map_t; |
#define GXEMUL_KBD_ADDRESS 0x10000000 |
#define GXEMUL_MP_ADDRESS 0x11000000 |
#define GXEMUL_FB_ADDRESS 0x12000000 |
#define GXEMUL_RTC_ADDRESS 0x15000000 |
#define GXEMUL_IRQC_ADDRESS 0x16000000 |
extern void gxemul_hw_map_init(void); |
extern void gxemul_console_init(devno_t devno); |
extern void gxemul_release_console(void); |
extern void gxemul_grab_console(void); |
extern void gxemul_timer_irq_start(void); |
extern void gxemul_debug_putc(char ch); |
extern void gxemul_cpu_halt(void); |
extern void gxemul_irq_exception(int exc_no, istate_t *istate); |
extern size_t gxemul_get_memory_size(void); |
extern uintptr_t gxemul_get_fb_address(void); |
extern void *gxemul_kbd; |
extern void *gxemul_rtc; |
extern void *gxemul_irqc; |
#define GXEMUL_HALT_OFFSET 0x010 |
#define GXEMUL_RTC_FREQ_OFFSET 0x100 |
#define GXEMUL_MP_MEMSIZE_OFFSET 0x090 |
#define GXEMUL_RTC_ACK_OFFSET 0x110 |
extern void gxemul_init(void); |
#endif |
/** @} |
/trunk/kernel/arch/arm32/Makefile.inc |
---|
51,7 → 51,6 |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/debug/print.c \ |
arch/$(KARCH)/src/console.c \ |
arch/$(KARCH)/src/exception.c \ |
arch/$(KARCH)/src/userspace.c \ |
/trunk/kernel/arch/arm32/src/debug/print.c |
---|
File deleted |
/trunk/kernel/arch/arm32/src/exception.c |
---|
34,13 → 34,12 |
*/ |
#include <arch/exception.h> |
#include <arch/debug/print.h> |
#include <arch/memstr.h> |
#include <arch/regutils.h> |
#include <interrupt.h> |
#include <arch/machine.h> |
#include <arch/mm/page_fault.h> |
#include <arch/barrier.h> |
#include <arch/drivers/gxemul.h> |
#include <print.h> |
#include <syscall/syscall.h> |
260,7 → 259,10 |
/** Low-level Prefetch Abort Exception handler. */ |
static void prefetch_abort_exception_entry(void) |
{ |
asm("sub lr, lr, #4"); |
asm volatile ( |
"sub lr, lr, #4" |
); |
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT); |
} |
267,7 → 269,10 |
/** Low-level Data Abort Exception handler. */ |
static void data_abort_exception_entry(void) |
{ |
asm("sub lr, lr, #8"); |
asm volatile ( |
"sub lr, lr, #8" |
); |
PROCESS_EXCEPTION(EXC_DATA_ABORT); |
} |
279,7 → 284,10 |
*/ |
static void irq_exception_entry(void) |
{ |
asm("sub lr, lr, #4"); |
asm volatile ( |
"sub lr, lr, #4" |
); |
setup_stack_and_save_regs(); |
switch_to_irq_servicing_mode(); |
299,6 → 307,12 |
istate->r3, istate->r4, istate->r5, istate->r6); |
} |
/** Returns the mask of active interrupts. */ |
static inline uint32_t gxemul_irqc_get_sources(void) |
{ |
return *((uint32_t *) gxemul_irqc); |
} |
/** Interrupt Exception handler. |
* |
* Determines the sources of interrupt and calls their handlers. |
305,8 → 319,24 |
*/ |
static void irq_exception(int exc_no, istate_t *istate) |
{ |
machine_irq_exception(exc_no, istate); |
uint32_t sources = gxemul_irqc_get_sources(); |
unsigned int i; |
for (i = 0; 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); |
spinlock_unlock(&irq->lock); |
} else { |
/* Spurious interrupt.*/ |
printf("cpu%d: spurious interrupt (inum=%d)\n", |
CPU->id, i); |
} |
} |
} |
} |
/** Fills exception vectors with appropriate exception handlers. */ |
void install_exception_handlers(void) |
379,18 → 409,18 |
*/ |
void print_istate(istate_t *istate) |
{ |
dprintf("istate dump:\n"); |
printf("istate dump:\n"); |
dprintf(" r0: %x r1: %x r2: %x r3: %x\n", |
printf(" r0: %x r1: %x r2: %x r3: %x\n", |
istate->r0, istate->r1, istate->r2, istate->r3); |
dprintf(" r4: %x r5: %x r6: %x r7: %x\n", |
printf(" r4: %x r5: %x r6: %x r7: %x\n", |
istate->r4, istate->r5, istate->r6, istate->r7); |
dprintf(" r8: %x r8: %x r10: %x r11: %x\n", |
printf(" r8: %x r8: %x r10: %x r11: %x\n", |
istate->r8, istate->r9, istate->r10, istate->r11); |
dprintf(" r12: %x sp: %x lr: %x spsr: %x\n", |
printf(" r12: %x sp: %x lr: %x spsr: %x\n", |
istate->r12, istate->sp, istate->lr, istate->spsr); |
dprintf(" pc: %x\n", istate->pc); |
printf(" pc: %x\n", istate->pc); |
} |
/** @} |
/trunk/kernel/arch/arm32/src/console.c |
---|
35,8 → 35,6 |
#include <console/console.h> |
#include <arch/console.h> |
#include <arch/machine.h> |
#include <genarch/fb/fb.h> |
/** Acquire console back for kernel. */ |
/trunk/kernel/arch/arm32/src/arm32.c |
---|
39,13 → 39,16 |
#include <ddi/device.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <genarch/drivers/dsrln/dsrlnin.h> |
#include <genarch/drivers/dsrln/dsrlnout.h> |
#include <genarch/srln/srln.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/irq.h> |
#include <arch/debug/print.h> |
#include <arch/drivers/gxemul.h> |
#include <print.h> |
#include <config.h> |
#include <interrupt.h> |
#include <arch/regutils.h> |
#include <arch/machine.h> |
#include <userspace.h> |
#include <macros.h> |
#include <string.h> |
75,18 → 78,15 |
/** Performs arm32 specific initialization afterr mm is initialized. */ |
void arch_post_mm_init(void) |
{ |
machine_hw_map_init(); |
gxemul_init(); |
/* Initialize exception dispatch table */ |
exception_init(); |
interrupt_init(); |
machine_console_init(device_assign_devno()); |
#ifdef CONFIG_FB |
fb_properties_t prop = { |
.addr = machine_get_fb_address(), |
.addr = GXEMUL_FB_ADDRESS, |
.offset = 0, |
.x = 640, |
.y = 480, |
94,7 → 94,11 |
.visual = VISUAL_BGR_8_8_8, |
}; |
fb_init(&prop); |
#endif |
#else |
#ifdef CONFIG_ARM_PRN |
dsrlnout_init((ioport8_t *) gxemul_kbd); |
#endif /* CONFIG_ARM_PRN */ |
#endif /* CONFIG_FB */ |
} |
/** Performs arm32 specific tasks needed after cpu is initialized. |
123,6 → 127,26 |
*/ |
void arch_post_smp_init(void) |
{ |
#ifdef CONFIG_ARM_KBD |
devno_t devno = device_assign_devno(); |
/* |
* Initialize the msim/GXemul keyboard port. Then initialize the serial line |
* module and connect it to the msim/GXemul keyboard. Enable keyboard interrupts. |
*/ |
indev_t *kbrdin = dsrlnin_init((dsrlnin_t *) gxemul_kbd, devno, GXEMUL_KBD_IRQ); |
if (kbrdin) |
srln_init(kbrdin); |
/* |
* This is the necessary evil until the userspace driver is entirely |
* self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd); |
#endif |
} |
156,7 → 180,8 |
/** Halts CPU. */ |
void cpu_halt(void) |
{ |
machine_cpu_halt(); |
*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET)) |
= 0; |
} |
/** Reboot. */ |
/trunk/kernel/arch/arm32/src/mm/page_fault.c |
---|
34,7 → 34,6 |
*/ |
#include <panic.h> |
#include <arch/exception.h> |
#include <arch/debug/print.h> |
#include <arch/mm/page_fault.h> |
#include <mm/as.h> |
#include <genarch/mm/page_pt.h> |
182,7 → 181,7 |
if (ret == AS_PF_FAULT) { |
print_istate(istate); |
dprintf("page fault - pc: %x, va: %x, status: %x(%x), " |
printf("page fault - pc: %x, va: %x, status: %x(%x), " |
"access:%d\n", istate->pc, badvaddr, fsr.status, fsr, |
access); |
201,7 → 200,7 |
int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate); |
if (ret == AS_PF_FAULT) { |
dprintf("prefetch_abort\n"); |
printf("prefetch_abort\n"); |
print_istate(istate); |
panic("page fault - prefetch_abort at address: %x.", |
istate->pc); |
/trunk/kernel/arch/arm32/src/mm/frame.c |
---|
35,9 → 35,8 |
#include <mm/frame.h> |
#include <arch/mm/frame.h> |
#include <arch/machine.h> |
#include <arch/drivers/gxemul.h> |
#include <config.h> |
#include <arch/debug/print.h> |
/** Address of the last frame in the memory. */ |
uintptr_t last_frame = 0; |
45,10 → 44,11 |
/** Creates memory zones. */ |
void frame_arch_init(void) |
{ |
/* all memory as one zone */ |
zone_create(0, ADDR2PFN(machine_get_memory_size()), |
last_frame = *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET)); |
/* All memory as one zone */ |
zone_create(0, ADDR2PFN(last_frame), |
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0); |
last_frame = machine_get_memory_size(); |
/* blacklist boot page table */ |
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME, |
58,11 → 58,10 |
/** Frees the boot page table. */ |
void boot_page_table_free(void) |
{ |
int i; |
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++) { |
unsigned int i; |
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++) |
frame_free(i * FRAME_SIZE + BOOT_PAGE_TABLE_ADDRESS); |
} |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/src/mm/page.c |
---|
51,19 → 51,15 |
*/ |
void page_arch_init(void) |
{ |
uintptr_t cur; |
int flags; |
int flags = PAGE_CACHEABLE; |
page_mapping_operations = &pt_mapping_operations; |
flags = PAGE_CACHEABLE; |
/* PA2KA(identity) mapping for all frames until last_frame */ |
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { |
uintptr_t cur; |
/* Kernel identity mapping */ |
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
/* create mapping for exception table at high offset */ |
/* Create mapping for exception table at high offset */ |
#ifdef HIGH_EXCEPTION_VECTORS |
void *virtaddr = frame_alloc(ONE_FRAME, FRAME_KA); |
page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, KA2PA(virtaddr), flags); |
/trunk/kernel/arch/arm32/src/panic.S |
---|
31,5 → 31,5 |
.global panic_printf |
panic_printf: |
bl debug_printf |
bl printf |
bl cpu_halt |
/trunk/kernel/arch/arm32/src/interrupt.c |
---|
35,13 → 35,16 |
#include <arch/asm.h> |
#include <arch/regutils.h> |
#include <arch/drivers/gxemul.h> |
#include <ddi/irq.h> |
#include <arch/machine.h> |
#include <ddi/device.h> |
#include <interrupt.h> |
/** Initial size of a table holding interrupt handlers. */ |
#define IRQ_COUNT 8 |
static irq_t gxemul_timer_irq; |
/** Disable interrupts. |
* |
* @return Old interrupt priority level. |
88,6 → 91,41 |
return current_status_reg_read(); |
} |
/** Starts gxemul Real Time Clock device, which asserts regular interrupts. |
* |
* @param frequency Interrupts frequency (0 disables RTC). |
*/ |
static void gxemul_timer_start(uint32_t frequency) |
{ |
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET)) |
= frequency; |
} |
static irq_ownership_t gxemul_timer_claim(irq_t *irq) |
{ |
return IRQ_ACCEPT; |
} |
/** Timer interrupt handler. |
* |
* @param irq Interrupt information. |
* @param arg Not used. |
*/ |
static void gxemul_timer_irq_handler(irq_t *irq) |
{ |
/* |
* We are holding a lock which prevents preemption. |
* Release the lock, call clock() and reacquire the lock again. |
*/ |
spinlock_unlock(&irq->lock); |
clock(); |
spinlock_lock(&irq->lock); |
/* acknowledge tick */ |
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET)) |
= 0; |
} |
/** Initialize basic tables for exception dispatching |
* and starts the timer. |
*/ |
94,7 → 132,16 |
void interrupt_init(void) |
{ |
irq_init(IRQ_COUNT, IRQ_COUNT); |
machine_timer_irq_start(); |
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); |
gxemul_timer_start(GXEMUL_TIMER_FREQ); |
} |
/** @} |
/trunk/kernel/arch/arm32/src/drivers/gxemul.c |
---|
33,333 → 33,19 |
* @brief GXemul drivers. |
*/ |
#include <interrupt.h> |
#include <console/chardev.h> |
#include <arch/drivers/gxemul.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <print.h> |
#include <ddi/device.h> |
#include <mm/page.h> |
#include <arch/machine.h> |
#include <arch/debug/print.h> |
/* Addresses of devices. */ |
#define GXEMUL_VIDEORAM 0x10000000 |
#define GXEMUL_KBD 0x10000000 |
#define GXEMUL_HALT_OFFSET 0x10 |
#define GXEMUL_RTC 0x15000000 |
#define GXEMUL_RTC_FREQ_OFFSET 0x100 |
#define GXEMUL_RTC_ACK_OFFSET 0x110 |
#define GXEMUL_IRQC 0x16000000 |
#define GXEMUL_IRQC_MASK_OFFSET 0x4 |
#define GXEMUL_IRQC_UNMASK_OFFSET 0x8 |
#define GXEMUL_MP 0x11000000 |
#define GXEMUL_MP_MEMSIZE_OFFSET 0x0090 |
#define GXEMUL_FB 0x12000000 |
void *gxemul_kbd; |
void *gxemul_rtc; |
void *gxemul_irqc; |
/* IRQs */ |
#define GXEMUL_KBD_IRQ 2 |
#define GXEMUL_TIMER_IRQ 4 |
static gxemul_hw_map_t gxemul_hw_map; |
static chardev_t console; |
static irq_t gxemul_console_irq; |
static irq_t gxemul_timer_irq; |
static bool hw_map_init_called = false; |
static void gxemul_kbd_enable(chardev_t *dev); |
static void gxemul_kbd_disable(chardev_t *dev); |
static void gxemul_write(chardev_t *dev, const char ch, bool silent); |
static char gxemul_do_read(chardev_t *dev); |
static chardev_operations_t gxemul_ops = { |
.resume = gxemul_kbd_enable, |
.suspend = gxemul_kbd_disable, |
.write = gxemul_write, |
.read = gxemul_do_read, |
}; |
/** Returns the mask of active interrupts. */ |
static inline uint32_t gxemul_irqc_get_sources(void) |
void gxemul_init(void) |
{ |
return *((uint32_t *) gxemul_hw_map.irqc); |
gxemul_kbd = (void *) hw_map(GXEMUL_KBD_ADDRESS, PAGE_SIZE); |
gxemul_rtc = (void *) hw_map(GXEMUL_RTC_ADDRESS, PAGE_SIZE); |
gxemul_irqc = (void *) hw_map(GXEMUL_IRQC_ADDRESS, PAGE_SIZE); |
} |
/** Masks interrupt. |
* |
* @param irq interrupt number |
*/ |
static inline void gxemul_irqc_mask(uint32_t irq) |
{ |
*((uint32_t *) gxemul_hw_map.irqc_mask) = irq; |
} |
/** Unmasks interrupt. |
* |
* @param irq interrupt number |
*/ |
static inline void gxemul_irqc_unmask(uint32_t irq) |
{ |
*((uint32_t *) gxemul_hw_map.irqc_unmask) = irq; |
} |
/** Initializes #gxemul_hw_map. */ |
void gxemul_hw_map_init(void) |
{ |
gxemul_hw_map.videoram = hw_map(GXEMUL_VIDEORAM, PAGE_SIZE); |
gxemul_hw_map.kbd = hw_map(GXEMUL_KBD, PAGE_SIZE); |
gxemul_hw_map.rtc = hw_map(GXEMUL_RTC, PAGE_SIZE); |
gxemul_hw_map.irqc = hw_map(GXEMUL_IRQC, PAGE_SIZE); |
gxemul_hw_map.rtc_freq = gxemul_hw_map.rtc + GXEMUL_RTC_FREQ_OFFSET; |
gxemul_hw_map.rtc_ack = gxemul_hw_map.rtc + GXEMUL_RTC_ACK_OFFSET; |
gxemul_hw_map.irqc_mask = gxemul_hw_map.irqc + GXEMUL_IRQC_MASK_OFFSET; |
gxemul_hw_map.irqc_unmask = gxemul_hw_map.irqc + |
GXEMUL_IRQC_UNMASK_OFFSET; |
hw_map_init_called = true; |
} |
/** Putchar that works with gxemul. |
* |
* @param dev Not used. |
* @param ch Characted to be printed. |
*/ |
static void gxemul_write(chardev_t *dev, const char ch, bool silent) |
{ |
if (!silent) |
*((char *) gxemul_hw_map.videoram) = ch; |
} |
/** Enables gxemul keyboard (interrupt unmasked). |
* |
* @param dev Not used. |
* |
* Called from getc(). |
*/ |
static void gxemul_kbd_enable(chardev_t *dev) |
{ |
gxemul_irqc_unmask(GXEMUL_KBD_IRQ); |
} |
/** Disables gxemul keyboard (interrupt masked). |
* |
* @param dev not used |
* |
* Called from getc(). |
*/ |
static void gxemul_kbd_disable(chardev_t *dev) |
{ |
gxemul_irqc_mask(GXEMUL_KBD_IRQ); |
} |
/** Read character using polling, assume interrupts disabled. |
* |
* @param dev Not used. |
*/ |
static char gxemul_do_read(chardev_t *dev) |
{ |
char ch; |
while (1) { |
ch = *((volatile char *) gxemul_hw_map.kbd); |
if (ch) { |
if (ch == '\r') |
return '\n'; |
if (ch == 0x7f) |
return '\b'; |
return ch; |
} |
} |
} |
/** Process keyboard interrupt. |
* |
* @param irq IRQ information. |
*/ |
static void gxemul_irq_handler(irq_t *irq) |
{ |
char ch = 0; |
ch = *((char *) gxemul_hw_map.kbd); |
if (ch == '\r') { |
ch = '\n'; |
} |
if (ch == 0x7f) { |
ch = '\b'; |
} |
chardev_push_character(&console, ch); |
} |
static irq_ownership_t gxemul_claim(irq_t *irq) |
{ |
return IRQ_ACCEPT; |
} |
/** Initializes console object representing gxemul console. |
* |
* @param devno device number. |
*/ |
void gxemul_console_init(devno_t devno) |
{ |
chardev_initialize("gxemul_console", &console, &gxemul_ops); |
stdin = &console; |
stdout = &console; |
irq_initialize(&gxemul_console_irq); |
gxemul_console_irq.devno = devno; |
gxemul_console_irq.inr = GXEMUL_KBD_IRQ; |
gxemul_console_irq.claim = gxemul_claim; |
gxemul_console_irq.handler = gxemul_irq_handler; |
irq_register(&gxemul_console_irq); |
gxemul_irqc_unmask(GXEMUL_KBD_IRQ); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, gxemul_hw_map.kbd); |
} |
/** Starts gxemul Real Time Clock device, which asserts regular interrupts. |
* |
* @param frequency Interrupts frequency (0 disables RTC). |
*/ |
static void gxemul_timer_start(uint32_t frequency) |
{ |
*((uint32_t*) gxemul_hw_map.rtc_freq) = frequency; |
} |
static irq_ownership_t gxemul_timer_claim(irq_t *irq) |
{ |
return IRQ_ACCEPT; |
} |
/** Timer interrupt handler. |
* |
* @param irq Interrupt information. |
* @param arg Not used. |
*/ |
static void gxemul_timer_irq_handler(irq_t *irq) |
{ |
/* |
* We are holding a lock which prevents preemption. |
* Release the lock, call clock() and reacquire the lock again. |
*/ |
spinlock_unlock(&irq->lock); |
clock(); |
spinlock_lock(&irq->lock); |
/* acknowledge tick */ |
*((uint32_t*) gxemul_hw_map.rtc_ack) = 0; |
} |
/** Initializes and registers timer interrupt handler. */ |
static void gxemul_timer_irq_init(void) |
{ |
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); |
} |
/** Starts timer. |
* |
* Initiates regular timer interrupts after initializing |
* corresponding interrupt handler. |
*/ |
void gxemul_timer_irq_start(void) |
{ |
gxemul_timer_irq_init(); |
gxemul_timer_start(GXEMUL_TIMER_FREQ); |
} |
/** Returns the size of emulated memory. |
* |
* @return Size in bytes. |
*/ |
size_t gxemul_get_memory_size(void) |
{ |
return *((int *) (GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET)); |
} |
/** Prints a character. |
* |
* @param ch Character to be printed. |
*/ |
void gxemul_debug_putc(char ch) |
{ |
char *addr = 0; |
if (!hw_map_init_called) { |
addr = (char *) GXEMUL_KBD; |
} else { |
addr = (char *) gxemul_hw_map.videoram; |
} |
*(addr) = ch; |
} |
/** Stops gxemul. */ |
void gxemul_cpu_halt(void) |
{ |
char * addr = 0; |
if (!hw_map_init_called) { |
addr = (char *) GXEMUL_KBD; |
} else { |
addr = (char *) gxemul_hw_map.videoram; |
} |
*(addr + GXEMUL_HALT_OFFSET) = '\0'; |
} |
/** Gxemul specific interrupt exception handler. |
* |
* Determines sources of the interrupt from interrupt controller and |
* calls high-level handlers for them. |
* |
* @param exc_no Interrupt exception number. |
* @param istate Saved processor state. |
*/ |
void gxemul_irq_exception(int exc_no, istate_t *istate) |
{ |
uint32_t sources = gxemul_irqc_get_sources(); |
int i; |
for (i = 0; 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); |
spinlock_unlock(&irq->lock); |
} else { |
/* Spurious interrupt.*/ |
dprintf("cpu%d: spurious interrupt (inum=%d)\n", |
CPU->id, i); |
} |
} |
} |
} |
/** Returns address of framebuffer device. |
* |
* @return Address of framebuffer device. |
*/ |
uintptr_t gxemul_get_fb_address(void) |
{ |
return (uintptr_t) GXEMUL_FB; |
} |
/** @} |
*/ |
/trunk/HelenOS.config |
---|
46,10 → 46,6 |
! [PLATFORM=mips32] MACHINE (choice) |
% Machine type |
@ "gxemul" GXEmul |
! [PLATFORM=arm32] MACHINE (choice) |
% Machine type |
@ "i460GX" i460GX chipset machine |
@ "ski" Ski ia64 simulator |
! [PLATFORM=ia64] MACHINE (choice) |
333,7 → 329,7 |
% Input device class |
@ "generic" Keyboard or serial line |
@ "none" No input device |
! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=mips32] CONFIG_HID_IN (choice) |
! [PLATFORM=ia32|PLATFORM=arm32|PLATFORM=amd64|PLATFORM=mips32] CONFIG_HID_IN (choice) |
% Output device class |
@ "generic" Monitor or serial line |
347,6 → 343,13 |
@ "none" No output device |
! [PLATFORM=mips32&(MACHINE=bgxemul|MACHINE=lgxemul)] CONFIG_HID_OUT (choice) |
% Output device class |
@ "generic" Monitor or serial line |
@ "monitor" Monitor |
@ "serial" Serial line |
@ "none" No output device |
! [PLATFORM=arm32] CONFIG_HID_OUT (choice) |
% PC keyboard support |
! [CONFIG_HID_IN=generic&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_PC_KBD (y/n) |
356,14 → 359,20 |
% Support for msim/GXemul printer |
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=mips32] CONFIG_MIPS_PRN (y/n) |
% Support for GXemul keyboard |
! [CONFIG_HID_IN=generic&PLATFORM=arm32] CONFIG_ARM_KBD (y/n) |
% Support for GXemul printer |
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32] CONFIG_ARM_PRN (y/n) |
% i8042 controller support |
! [CONFIG_PC_KBD=y] CONFIG_I8042 (y) |
% Dummy serial line input |
! [CONFIG_MIPS_KBD=y] CONFIG_DSRLNIN (y) |
! [CONFIG_MIPS_KBD=y|CONFIG_ARM_KBD=y] CONFIG_DSRLNIN (y) |
% Dummy serial line output |
! [CONFIG_MIPS_PRN=y] CONFIG_DSRLNOUT (y) |
! [CONFIG_MIPS_PRN=y|CONFIG_ARM_PRN=y] CONFIG_DSRLNOUT (y) |
% Serial line input module |
! [CONFIG_DSRLNIN=y] CONFIG_SRLN (y) |
399,6 → 408,9 |
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=monitor)&PLATFORM=mips32&(MACHINE=lgxemul|MACHINE=bgxemul)] CONFIG_FB (y/n) |
% Framebuffer support |
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=monitor)&PLATFORM=arm32] CONFIG_FB (y/n) |
% Framebuffer support |
! [CONFIG_HID_OUT=none] CONFIG_FB (n) |
% Framebuffer width |
/trunk/defaults/arm32/Makefile.config |
---|
23,13 → 23,10 |
CONFIG_TEST = y |
# What is your input device? |
CONFIG_HID_IN = keyboard |
CONFIG_HID_IN = generic |
# What is your output device? |
CONFIG_HID_OUT = monitor |
CONFIG_HID_OUT = generic |
# Framebuffer support |
CONFIG_FB = y |
# Keyboard layout |
KBD_LAYOUT = us_qwerty |