50,6 → 50,9 |
/* Addresses of devices. */ |
#define QEMU_ICP_VIDEORAM 0x16000000 |
#define QEMU_ICP_KBD 0x18000000 |
#define ICP_KBD_STAT 0x04 |
#define ICP_KBD_DATA 0x08 |
#define ICP_KBD_INTR_STAT 0x10 |
#define QEMU_ICP_HALT_OFFSET 0x10 |
#define QEMU_ICP_RTC 0x13000000 |
#define QEMU_ICP_RTC1_LOAD_OFFSET 0x100 |
63,7 → 66,7 |
#define QEMU_ICP_IRQC_UNMASK_OFFSET 0x8 |
#define QEMU_ICP_MP 0x11000000 |
#define QEMU_ICP_MP_MEMSIZE_OFFSET 0x0090 |
#define QEMU_ICP_FB 0x94000 |
#define QEMU_ICP_FB 0x01000000 |
|
#define ICP_VGA 0xC0000000 |
#define ICP_CMCR 0x10000000 |
145,7 → 148,10 |
void qemu_icp_hw_map_init(void) |
{ |
qemu_icp_hw_map.videoram = hw_map(QEMU_ICP_VIDEORAM, PAGE_SIZE); |
qemu_icp_hw_map.kbd = hw_map(QEMU_ICP_KBD, PAGE_SIZE); |
qemu_icp_hw_map.kbd_ctrl = hw_map(QEMU_ICP_KBD, PAGE_SIZE); |
qemu_icp_hw_map.kbd_stat = qemu_icp_hw_map.kbd_ctrl + ICP_KBD_STAT; |
qemu_icp_hw_map.kbd_data = qemu_icp_hw_map.kbd_ctrl + ICP_KBD_DATA; |
qemu_icp_hw_map.kbd_intstat = qemu_icp_hw_map.kbd_ctrl + ICP_KBD_INTR_STAT; |
qemu_icp_hw_map.rtc = hw_map(QEMU_ICP_RTC, PAGE_SIZE); |
qemu_icp_hw_map.rtc1_load = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_LOAD_OFFSET; |
qemu_icp_hw_map.rtc1_read = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_READ_OFFSET; |
207,7 → 213,7 |
char ch; |
|
while (1) { |
ch = *((volatile char *) qemu_icp_hw_map.kbd); |
ch = *((volatile char *) qemu_icp_hw_map.kbd_data); |
if (ch) { |
if (ch == '\r') |
return '\n'; |
230,7 → 236,7 |
} else { |
char ch = 0; |
|
ch = *((char *) qemu_icp_hw_map.kbd); |
ch = *((char *) qemu_icp_hw_map.kbd_data); |
if (ch == '\r') { |
ch = '\n'; |
} |
275,11 → 281,11 |
*/ |
void qemu_icp_console_init(devno_t devno) |
{ |
qemu_icp_irqc_mask(QEMU_ICP_KBD_IRQ); |
chardev_initialize("qemu_icp_console", &console, &qemu_icp_ops); |
stdin = &console; |
stdout = &console; |
|
qemu_icp_irqc_mask(QEMU_ICP_KBD_IRQ); |
irq_initialize(&qemu_icp_console_irq); |
qemu_icp_console_irq.devno = devno; |
qemu_icp_console_irq.inr = QEMU_ICP_KBD_IRQ; |
286,6 → 292,8 |
qemu_icp_console_irq.claim = qemu_icp_claim; |
qemu_icp_console_irq.handler = qemu_icp_irq_handler; |
irq_register(&qemu_icp_console_irq); |
|
*(char *)qemu_icp_hw_map.kbd_ctrl = 0x17; |
|
qemu_icp_irqc_unmask(QEMU_ICP_KBD_IRQ); |
|
292,7 → 300,7 |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, QEMU_ICP_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, qemu_icp_hw_map.kbd); |
sysinfo_set_item_val("kbd.address.virtual", NULL, qemu_icp_hw_map.kbd_data); |
} |
|
/** Starts qemu_icp Real Time Clock device, which asserts regular interrupts. |
310,7 → 318,6 |
|
static irq_ownership_t qemu_icp_timer_claim(void) |
{ |
*((uint32_t*) qemu_icp_hw_map.rtc1_intrclr) = 1; |
return IRQ_ACCEPT; |
} |
|
325,6 → 332,7 |
* We are holding a lock which prevents preemption. |
* Release the lock, call clock() and reacquire the lock again. |
*/ |
*((uint32_t*) qemu_icp_hw_map.rtc1_intrclr) = 1; |
spinlock_unlock(&irq->lock); |
clock(); |
spinlock_lock(&irq->lock); |
386,14 → 394,7 |
/** Stops qemu_icp. */ |
void qemu_icp_cpu_halt(void) |
{ |
char * addr = 0; |
if (!hw_map_init_called) { |
addr = (char *) QEMU_ICP_KBD; |
} else { |
addr = (char *) qemu_icp_hw_map.videoram; |
} |
|
*(addr + QEMU_ICP_HALT_OFFSET) = '\0'; |
while (1); |
} |
|
/** Gxemul specific interrupt exception handler. |