83,7 → 83,6 |
.read = gxemul_do_read, |
}; |
|
|
/** Returns the mask of active interrupts. */ |
static inline uint32_t gxemul_irqc_get_sources(void) |
{ |
90,7 → 89,6 |
return *(uint32_t*) gxemul_hw_map.irqc; |
} |
|
|
/** Masks interrupt. |
* |
* @param irq interrupt number |
100,7 → 98,6 |
*(uint32_t*) gxemul_hw_map.irqc_mask = irq; |
} |
|
|
/** Unmasks interrupt. |
* |
* @param irq interrupt number |
110,7 → 107,6 |
*(uint32_t*) gxemul_hw_map.irqc_unmask = irq; |
} |
|
|
/** Initializes #gxemul_hw_map. */ |
void machine_hw_map_init(void) |
{ |
118,7 → 114,6 |
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.fb = hw_map(GXEMUL_FB, 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; |
128,7 → 123,6 |
hw_map_init_called = true; |
} |
|
|
/** Putchar that works with gxemul */ |
static void gxemul_write(chardev_t *dev, const char ch) |
{ |
135,7 → 129,6 |
*((char *) gxemul_hw_map.videoram) = ch; |
} |
|
|
/* Called from getc(). */ |
static void gxemul_enable(chardev_t *dev) |
{ |
142,7 → 135,6 |
gxemul_irqc_unmask(GXEMUL_KBD_IRQ); |
} |
|
|
/* Called from getc(). */ |
static void gxemul_disable(chardev_t *dev) |
{ |
149,11 → 141,7 |
gxemul_irqc_mask(GXEMUL_KBD_IRQ); |
} |
|
|
/** Read character using polling, assume interrupts disabled. |
* |
* @param dev Not used. |
*/ |
/** Read character using polling, assume interrupts disabled */ |
static char gxemul_do_read(chardev_t *dev) |
{ |
char ch; |
170,33 → 158,28 |
} |
} |
|
|
/** Process keyboard interrupt. */ |
static void gxemul_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) { |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
} else { |
else { |
char ch = 0; |
|
ch = *((char *) gxemul_hw_map.kbd); |
if (ch == '\r') { |
ch = '\n'; |
} |
if (ch == 0x7f) { |
ch = '\b'; |
} |
chardev_push_character(&console, ch); |
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(void) |
{ |
return IRQ_ACCEPT; |
} |
|
|
void machine_grab_console(void) |
{ |
ipl_t ipl = interrupts_disable(); |
206,23 → 189,18 |
interrupts_restore(ipl); |
} |
|
|
void machine_release_console(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&gxemul_irq.lock); |
if (gxemul_irq.notif_cfg.answerbox) { |
if (gxemul_irq.notif_cfg.answerbox) |
gxemul_irq.notif_cfg.notify = true; |
} |
spinlock_unlock(&gxemul_irq.lock); |
interrupts_restore(ipl); |
} |
|
|
/** Initializes console object representing gxemul console. |
* |
* @param Console device number. |
*/ |
/** Return console object representing gxemul console */ |
void machine_console_init(devno_t devno) |
{ |
chardev_initialize("gxemul_console", &console, &gxemul_ops); |
248,7 → 226,7 |
|
/** Starts gxemul Real Time Clock device, which asserts regular interrupts. |
* |
* @param frequency Interrupts frequency (0 disables RTC). |
* @param frequency interrupts frequency (0 disables RTC) |
*/ |
static void gxemul_timer_start(uint32_t frequency) |
{ |
255,17 → 233,14 |
*(uint32_t*) gxemul_hw_map.rtc_freq = frequency; |
} |
|
|
static irq_ownership_t gxemul_timer_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
|
|
/** Timer interrupt handler. |
* |
* @param irq Interrupt information. |
* @param arg Not used. |
* @param irq interrupt information |
*/ |
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...) |
{ |
298,8 → 273,8 |
*/ |
} |
|
|
/** Initializes and registers timer interrupt handler. */ |
/** Initializes and registers timer interrupt handler. |
*/ |
static void gxemul_timer_irq_init() |
{ |
irq_initialize(&gxemul_timer_irq); |
311,7 → 286,6 |
irq_register(&gxemul_timer_irq); |
} |
|
|
/** Starts timer. |
* |
* Initiates regular timer interrupts after initializing |
323,10 → 297,9 |
gxemul_timer_start(GXEMUL_TIMER_FREQ); |
} |
|
|
/** Returns the size of emulated memory. |
* |
* @return Size in bytes. |
* @return size in bytes |
*/ |
size_t machine_get_memory_size(void) |
{ |
333,7 → 306,6 |
return *((int*)(GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET)); |
} |
|
|
void machine_debug_putc(char ch) |
{ |
char * addr = 0; |
346,7 → 318,6 |
*(addr) = ch; |
} |
|
|
/** Stops gxemul. */ |
void machine_cpu_halt(void) |
{ |
360,14 → 331,13 |
*(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. |
* @param exc_no interrupt exception number |
* @param istate saved processor state |
*/ |
void machine_irq_exception(int exc_no, istate_t *istate) |
{ |
389,10 → 359,5 |
} |
|
|
uintptr_t machine_get_fb_address(void) |
{ |
return gxemul_hw_map.fb; |
} |
|
/** @} |
*/ |