1,5 → 1,5 |
/* |
* Copyright (c) 2005-2007 Ondrej Palkovsky, Michal Kebrt, Petr Stepan |
* Copyright (c) 2007 Michal Kebrt, Petr Stepan |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
40,21 → 40,26 |
#include <sysinfo/sysinfo.h> |
#include <print.h> |
#include <ddi/device.h> |
#include <mm/page.h> |
|
/** Address of devices. */ |
#define GXEMUL_VIDEORAM 0x10000000 |
#define GXEMUL_KBD_ADDRESS 0x10000000 |
#define GXEMUL_KBD 0x10000000 |
#define GXEMUL_RTC 0x15000000 |
#define GXEMUL_RTC_FREQ 0x15000100 |
#define GXEMUL_RTC_ACK 0x15000110 |
#define GXEMUL_RTC_FREQ_OFFSET 0x100 |
#define GXEMUL_RTC_ACK_OFFSET 0x110 |
#define GXEMUL_IRQC 0x16000000 |
#define GXEMUL_IRQC_MASK 0x16000004 |
#define GXEMUL_IRQC_UNMASK 0x16000008 |
#define GXEMUL_IRQC_MASK_OFFSET 0x4 |
#define GXEMUL_IRQC_UNMASK_OFFSET 0x8 |
#define GXEMUL_MP 0x11000000 |
#define GXEMUL_MP_MEMSIZE_OFFSET 0x0090 |
|
|
/** 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_irq; |
static irq_t gxemul_timer_irq; |
71,10 → 76,25 |
.read = gxemul_do_read, |
}; |
|
|
/** 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; |
} |
|
/** Putchar that works with gxemul */ |
void gxemul_write(chardev_t *dev, const char ch) |
{ |
*((char *) GXEMUL_VIDEORAM) = ch; |
*((char *) gxemul_hw_map.videoram) = ch; |
} |
|
/* Called from getc(). */ |
97,7 → 117,7 |
char ch; |
|
while (1) { |
ch = *((volatile char *) GXEMUL_KBD_ADDRESS); |
ch = *((volatile char *) gxemul_hw_map.kbd); |
if (ch) { |
if (ch == '\r') |
return '\n'; |
116,7 → 136,7 |
else { |
char ch = 0; |
|
ch = *((char *) GXEMUL_KBD_ADDRESS); |
ch = *((char *) gxemul_hw_map.kbd); |
if (ch =='\r') |
ch = '\n'; |
if (ch == 0x7f) |
134,7 → 154,7 |
void gxemul_kbd_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&msim_irq.lock); |
spinlock_lock(&gxemul_irq.lock); |
gxemul_irq.notif_cfg.notify = false; |
spinlock_unlock(&gxemul_irq.lock); |
interrupts_restore(ipl); |
151,10 → 171,10 |
} |
|
|
/** Return console object representing msim console */ |
/** Return console object representing gxemul console */ |
void gxemul_console(devno_t devno) |
{ |
chardev_initialize("msim_console", &console, &gxemul_ops); |
chardev_initialize("gxemul_console", &console, &gxemul_ops); |
stdin = &console; |
stdout = &console; |
|
171,13 → 191,13 |
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_KBD_ADDRESS); |
sysinfo_set_item_val("kbd.address.virtual", NULL, gxemul_hw_map.kbd); |
} |
|
/** Return the mask of active interrupts. */ |
inline uint32_t gxemul_irqc_get_sources(void) |
{ |
return *(uint32_t*) GXEMUL_IRQC; |
return *(uint32_t*) gxemul_hw_map.irqc; |
} |
|
/** Masks interrupt. |
186,7 → 206,7 |
*/ |
inline void gxemul_irqc_mask(uint32_t irq) |
{ |
*(uint32_t*) GXEMUL_IRQC_MASK = irq; |
*(uint32_t*) gxemul_hw_map.irqc_mask = irq; |
} |
|
/** Unmasks interrupt. |
195,7 → 215,7 |
*/ |
inline void gxemul_irqc_unmask(uint32_t irq) |
{ |
*(uint32_t*) GXEMUL_IRQC_UNMASK = irq; |
*(uint32_t*) gxemul_hw_map.irqc_unmask = irq; |
} |
|
|
205,7 → 225,7 |
*/ |
void gxemul_timer_start(uint32_t frequency) |
{ |
*(uint32_t*) GXEMUL_RTC_FREQ = frequency; |
*(uint32_t*) gxemul_hw_map.rtc_freq = frequency; |
} |
|
static irq_ownership_t gxemul_timer_claim(void) |
237,7 → 257,7 |
spinlock_lock(&irq->lock); |
|
/* acknowledge tick */ |
*(uint32_t*) GXEMUL_RTC_ACK = 0; |
*(uint32_t*) gxemul_hw_map.rtc_ack = 0; |
|
/* TODO what's that? * |
if (virtual_timer_fnc != NULL) |
259,6 → 279,10 |
irq_register(&gxemul_timer_irq); |
} |
|
size_t gxemul_get_memory_size(void) |
{ |
return *((int*)(GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET)); |
} |
|
/** @} |
*/ |