|
1 import qemu |
|
2 |
|
3 class syborg_keyboard(qemu.devclass): |
|
4 REG_ID = 0 |
|
5 REG_DATA = 1 |
|
6 REG_FIFO_COUNT = 2 |
|
7 REG_INT_ENABLE = 3 |
|
8 REG_FIFO_SIZE = 4 |
|
9 |
|
10 def update_irq(self): |
|
11 self.set_irq_level(0, (len(self.fifo) > 0) and self.int_enabled) |
|
12 |
|
13 def event(self, keycode): |
|
14 if (keycode == 0xe0) and not self.extension_bit: |
|
15 self.extension_bit = 0x80 |
|
16 return |
|
17 val = (keycode & 0x7f) | self.extension_bit |
|
18 if (keycode & 0x80) != 0: |
|
19 val |= 0x80000000 |
|
20 self.extension_bit = 0 |
|
21 if len(self.fifo) < self.fifo_size: |
|
22 self.fifo.append(val) |
|
23 self.update_irq() |
|
24 |
|
25 def create(self): |
|
26 self.fifo_size = self.properties["fifo-size"] |
|
27 self.fifo=[] |
|
28 self.int_enabled = False |
|
29 self.extension_bit = 0 |
|
30 qemu.register_keyboard(self.event) |
|
31 |
|
32 def read_reg(self, offset): |
|
33 offset >>= 2 |
|
34 if offset == self.REG_ID: |
|
35 return 0xc51d0002 |
|
36 elif offset == self.REG_DATA: |
|
37 if len(self.fifo) == 0: |
|
38 return 0xffffffff |
|
39 val = self.fifo.pop(0) |
|
40 self.update_irq(); |
|
41 return val |
|
42 elif offset == self.REG_FIFO_COUNT: |
|
43 return len(self.fifo) |
|
44 elif offset == self.REG_INT_ENABLE: |
|
45 return self.int_enabled |
|
46 elif offset == self.REG_FIFO_SIZE: |
|
47 return self.fifo_size |
|
48 return 0 |
|
49 |
|
50 def write_reg(self, offset, value): |
|
51 offset >>= 2 |
|
52 if offset == self.REG_INT_ENABLE: |
|
53 self.int_enabled = ((value & 1) != 0) |
|
54 self.update_irq() |
|
55 |
|
56 def save(self, f): |
|
57 f.put_u32(self.fifo_size) |
|
58 f.put_u32(self.int_enabled) |
|
59 f.put_u32(self.extension_bit) |
|
60 f.put_u32(len(self.fifo)) |
|
61 for x in self.fifo: |
|
62 f.put_u32(x) |
|
63 |
|
64 def load(self, f): |
|
65 if self.fifo_size != f.get_u32(): |
|
66 raise ValueError, "fifo size mismatch" |
|
67 self.int_enabled = f.get_u32() |
|
68 self.extension_bit = f.get_u32() |
|
69 n = f.get_u32() |
|
70 self.fifo = [] |
|
71 while n > 0: |
|
72 self.fifo.append(f.get_u32()) |
|
73 n -= 1; |
|
74 |
|
75 # Device class properties |
|
76 regions = [qemu.ioregion(0x1000, readl=read_reg, writel=write_reg)] |
|
77 irqs = 1 |
|
78 name = "syborg,keyboard" |
|
79 properties = {"fifo-size":16} |
|
80 |
|
81 qemu.register_device(syborg_keyboard) |