Rev 4615 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4615 | Rev 4628 | ||
---|---|---|---|
Line 48... | Line 48... | ||
48 | #include <genarch/fb/visuals.h> |
48 | #include <genarch/fb/visuals.h> |
49 | 49 | ||
50 | /* Addresses of devices. */ |
50 | /* Addresses of devices. */ |
51 | #define QEMU_ICP_VIDEORAM 0x16000000 |
51 | #define QEMU_ICP_VIDEORAM 0x16000000 |
52 | #define QEMU_ICP_KBD 0x18000000 |
52 | #define QEMU_ICP_KBD 0x18000000 |
- | 53 | #define ICP_KBD_STAT 0x04 |
|
- | 54 | #define ICP_KBD_DATA 0x08 |
|
- | 55 | #define ICP_KBD_INTR_STAT 0x10 |
|
53 | #define QEMU_ICP_HALT_OFFSET 0x10 |
56 | #define QEMU_ICP_HALT_OFFSET 0x10 |
54 | #define QEMU_ICP_RTC 0x13000000 |
57 | #define QEMU_ICP_RTC 0x13000000 |
55 | #define QEMU_ICP_RTC1_LOAD_OFFSET 0x100 |
58 | #define QEMU_ICP_RTC1_LOAD_OFFSET 0x100 |
56 | #define QEMU_ICP_RTC1_READ_OFFSET 0x104 |
59 | #define QEMU_ICP_RTC1_READ_OFFSET 0x104 |
57 | #define QEMU_ICP_RTC1_CTL_OFFSET 0x108 |
60 | #define QEMU_ICP_RTC1_CTL_OFFSET 0x108 |
Line 61... | Line 64... | ||
61 | #define QEMU_ICP_IRQC 0x14000000 |
64 | #define QEMU_ICP_IRQC 0x14000000 |
62 | #define QEMU_ICP_IRQC_MASK_OFFSET 0xC |
65 | #define QEMU_ICP_IRQC_MASK_OFFSET 0xC |
63 | #define QEMU_ICP_IRQC_UNMASK_OFFSET 0x8 |
66 | #define QEMU_ICP_IRQC_UNMASK_OFFSET 0x8 |
64 | #define QEMU_ICP_MP 0x11000000 |
67 | #define QEMU_ICP_MP 0x11000000 |
65 | #define QEMU_ICP_MP_MEMSIZE_OFFSET 0x0090 |
68 | #define QEMU_ICP_MP_MEMSIZE_OFFSET 0x0090 |
66 | #define QEMU_ICP_FB 0x94000 |
69 | #define QEMU_ICP_FB 0x01000000 |
67 | 70 | ||
68 | #define ICP_VGA 0xC0000000 |
71 | #define ICP_VGA 0xC0000000 |
69 | #define ICP_CMCR 0x10000000 |
72 | #define ICP_CMCR 0x10000000 |
70 | 73 | ||
71 | /* IRQs */ |
74 | /* IRQs */ |
Line 143... | Line 146... | ||
143 | 146 | ||
144 | /** Initializes #qemu_icp_hw_map. */ |
147 | /** Initializes #qemu_icp_hw_map. */ |
145 | void qemu_icp_hw_map_init(void) |
148 | void qemu_icp_hw_map_init(void) |
146 | { |
149 | { |
147 | qemu_icp_hw_map.videoram = hw_map(QEMU_ICP_VIDEORAM, PAGE_SIZE); |
150 | qemu_icp_hw_map.videoram = hw_map(QEMU_ICP_VIDEORAM, PAGE_SIZE); |
148 | qemu_icp_hw_map.kbd = hw_map(QEMU_ICP_KBD, PAGE_SIZE); |
151 | qemu_icp_hw_map.kbd_ctrl = hw_map(QEMU_ICP_KBD, PAGE_SIZE); |
- | 152 | qemu_icp_hw_map.kbd_stat = qemu_icp_hw_map.kbd_ctrl + ICP_KBD_STAT; |
|
- | 153 | qemu_icp_hw_map.kbd_data = qemu_icp_hw_map.kbd_ctrl + ICP_KBD_DATA; |
|
- | 154 | qemu_icp_hw_map.kbd_intstat = qemu_icp_hw_map.kbd_ctrl + ICP_KBD_INTR_STAT; |
|
149 | qemu_icp_hw_map.rtc = hw_map(QEMU_ICP_RTC, PAGE_SIZE); |
155 | qemu_icp_hw_map.rtc = hw_map(QEMU_ICP_RTC, PAGE_SIZE); |
150 | qemu_icp_hw_map.rtc1_load = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_LOAD_OFFSET; |
156 | qemu_icp_hw_map.rtc1_load = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_LOAD_OFFSET; |
151 | qemu_icp_hw_map.rtc1_read = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_READ_OFFSET; |
157 | qemu_icp_hw_map.rtc1_read = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_READ_OFFSET; |
152 | qemu_icp_hw_map.rtc1_ctl = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_CTL_OFFSET; |
158 | qemu_icp_hw_map.rtc1_ctl = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_CTL_OFFSET; |
153 | qemu_icp_hw_map.rtc1_intrclr = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_INTRCLR_OFFSET; |
159 | qemu_icp_hw_map.rtc1_intrclr = qemu_icp_hw_map.rtc + QEMU_ICP_RTC1_INTRCLR_OFFSET; |
Line 205... | Line 211... | ||
205 | static char qemu_icp_do_read(chardev_t *dev) |
211 | static char qemu_icp_do_read(chardev_t *dev) |
206 | { |
212 | { |
207 | char ch; |
213 | char ch; |
208 | 214 | ||
209 | while (1) { |
215 | while (1) { |
210 | ch = *((volatile char *) qemu_icp_hw_map.kbd); |
216 | ch = *((volatile char *) qemu_icp_hw_map.kbd_data); |
211 | if (ch) { |
217 | if (ch) { |
212 | if (ch == '\r') |
218 | if (ch == '\r') |
213 | return '\n'; |
219 | return '\n'; |
214 | if (ch == 0x7f) |
220 | if (ch == 0x7f) |
215 | return '\b'; |
221 | return '\b'; |
Line 228... | Line 234... | ||
228 | if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) { |
234 | if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) { |
229 | ipc_irq_send_notif(irq); |
235 | ipc_irq_send_notif(irq); |
230 | } else { |
236 | } else { |
231 | char ch = 0; |
237 | char ch = 0; |
232 | 238 | ||
233 | ch = *((char *) qemu_icp_hw_map.kbd); |
239 | ch = *((char *) qemu_icp_hw_map.kbd_data); |
234 | if (ch == '\r') { |
240 | if (ch == '\r') { |
235 | ch = '\n'; |
241 | ch = '\n'; |
236 | } |
242 | } |
237 | if (ch == 0x7f) { |
243 | if (ch == 0x7f) { |
238 | ch = '\b'; |
244 | ch = '\b'; |
Line 273... | Line 279... | ||
273 | * |
279 | * |
274 | * @param devno device number. |
280 | * @param devno device number. |
275 | */ |
281 | */ |
276 | void qemu_icp_console_init(devno_t devno) |
282 | void qemu_icp_console_init(devno_t devno) |
277 | { |
283 | { |
278 | qemu_icp_irqc_mask(QEMU_ICP_KBD_IRQ); |
- | |
279 | chardev_initialize("qemu_icp_console", &console, &qemu_icp_ops); |
284 | chardev_initialize("qemu_icp_console", &console, &qemu_icp_ops); |
280 | stdin = &console; |
285 | stdin = &console; |
281 | stdout = &console; |
286 | stdout = &console; |
282 | 287 | ||
- | 288 | qemu_icp_irqc_mask(QEMU_ICP_KBD_IRQ); |
|
283 | irq_initialize(&qemu_icp_console_irq); |
289 | irq_initialize(&qemu_icp_console_irq); |
284 | qemu_icp_console_irq.devno = devno; |
290 | qemu_icp_console_irq.devno = devno; |
285 | qemu_icp_console_irq.inr = QEMU_ICP_KBD_IRQ; |
291 | qemu_icp_console_irq.inr = QEMU_ICP_KBD_IRQ; |
286 | qemu_icp_console_irq.claim = qemu_icp_claim; |
292 | qemu_icp_console_irq.claim = qemu_icp_claim; |
287 | qemu_icp_console_irq.handler = qemu_icp_irq_handler; |
293 | qemu_icp_console_irq.handler = qemu_icp_irq_handler; |
288 | irq_register(&qemu_icp_console_irq); |
294 | irq_register(&qemu_icp_console_irq); |
- | 295 | ||
- | 296 | *(char *)qemu_icp_hw_map.kbd_ctrl = 0x17; |
|
289 | 297 | ||
290 | qemu_icp_irqc_unmask(QEMU_ICP_KBD_IRQ); |
298 | qemu_icp_irqc_unmask(QEMU_ICP_KBD_IRQ); |
291 | 299 | ||
292 | sysinfo_set_item_val("kbd", NULL, true); |
300 | sysinfo_set_item_val("kbd", NULL, true); |
293 | sysinfo_set_item_val("kbd.devno", NULL, devno); |
301 | sysinfo_set_item_val("kbd.devno", NULL, devno); |
294 | sysinfo_set_item_val("kbd.inr", NULL, QEMU_ICP_KBD_IRQ); |
302 | sysinfo_set_item_val("kbd.inr", NULL, QEMU_ICP_KBD_IRQ); |
295 | sysinfo_set_item_val("kbd.address.virtual", NULL, qemu_icp_hw_map.kbd); |
303 | sysinfo_set_item_val("kbd.address.virtual", NULL, qemu_icp_hw_map.kbd_data); |
296 | } |
304 | } |
297 | 305 | ||
298 | /** Starts qemu_icp Real Time Clock device, which asserts regular interrupts. |
306 | /** Starts qemu_icp Real Time Clock device, which asserts regular interrupts. |
299 | * |
307 | * |
300 | * @param frequency Interrupts frequency (0 disables RTC). |
308 | * @param frequency Interrupts frequency (0 disables RTC). |
Line 308... | Line 316... | ||
308 | qemu_icp_irqc_unmask(QEMU_ICP_TIMER_IRQ); |
316 | qemu_icp_irqc_unmask(QEMU_ICP_TIMER_IRQ); |
309 | } |
317 | } |
310 | 318 | ||
311 | static irq_ownership_t qemu_icp_timer_claim(void) |
319 | static irq_ownership_t qemu_icp_timer_claim(void) |
312 | { |
320 | { |
313 | *((uint32_t*) qemu_icp_hw_map.rtc1_intrclr) = 1; |
- | |
314 | return IRQ_ACCEPT; |
321 | return IRQ_ACCEPT; |
315 | } |
322 | } |
316 | 323 | ||
317 | /** Timer interrupt handler. |
324 | /** Timer interrupt handler. |
318 | * |
325 | * |
Line 323... | Line 330... | ||
323 | { |
330 | { |
324 | /* |
331 | /* |
325 | * We are holding a lock which prevents preemption. |
332 | * We are holding a lock which prevents preemption. |
326 | * Release the lock, call clock() and reacquire the lock again. |
333 | * Release the lock, call clock() and reacquire the lock again. |
327 | */ |
334 | */ |
- | 335 | *((uint32_t*) qemu_icp_hw_map.rtc1_intrclr) = 1; |
|
328 | spinlock_unlock(&irq->lock); |
336 | spinlock_unlock(&irq->lock); |
329 | clock(); |
337 | clock(); |
330 | spinlock_lock(&irq->lock); |
338 | spinlock_lock(&irq->lock); |
331 | 339 | ||
332 | } |
340 | } |
Line 384... | Line 392... | ||
384 | } |
392 | } |
385 | 393 | ||
386 | /** Stops qemu_icp. */ |
394 | /** Stops qemu_icp. */ |
387 | void qemu_icp_cpu_halt(void) |
395 | void qemu_icp_cpu_halt(void) |
388 | { |
396 | { |
389 | char * addr = 0; |
- | |
390 | if (!hw_map_init_called) { |
- | |
391 | addr = (char *) QEMU_ICP_KBD; |
- | |
392 | } else { |
397 | while (1); |
393 | addr = (char *) qemu_icp_hw_map.videoram; |
- | |
394 | } |
- | |
395 | - | ||
396 | *(addr + QEMU_ICP_HALT_OFFSET) = '\0'; |
- | |
397 | } |
398 | } |
398 | 399 | ||
399 | /** Gxemul specific interrupt exception handler. |
400 | /** Gxemul specific interrupt exception handler. |
400 | * |
401 | * |
401 | * Determines sources of the interrupt from interrupt controller and |
402 | * Determines sources of the interrupt from interrupt controller and |