pl050.c (4dad0a9aa818698e0735c8352bf7925a1660df6f) | pl050.c (600f71109d8a0c10205d0f9c344c47d5a7962eed) |
---|---|
1/* 2 * Arm PrimeCell PL050 Keyboard / Mouse Interface 3 * 4 * Copyright (c) 2006-2007 CodeSourcery. 5 * Written by Paul Brook 6 * 7 * This code is licensed under the GPL. 8 */ --- 39 unchanged lines hidden (view full) --- 48#define PL050_TXEMPTY (1 << 6) 49#define PL050_TXBUSY (1 << 5) 50#define PL050_RXFULL (1 << 4) 51#define PL050_RXBUSY (1 << 3) 52#define PL050_RXPARITY (1 << 2) 53#define PL050_KMIC (1 << 1) 54#define PL050_KMID (1 << 0) 55 | 1/* 2 * Arm PrimeCell PL050 Keyboard / Mouse Interface 3 * 4 * Copyright (c) 2006-2007 CodeSourcery. 5 * Written by Paul Brook 6 * 7 * This code is licensed under the GPL. 8 */ --- 39 unchanged lines hidden (view full) --- 48#define PL050_TXEMPTY (1 << 6) 49#define PL050_TXBUSY (1 << 5) 50#define PL050_RXFULL (1 << 4) 51#define PL050_RXBUSY (1 << 3) 52#define PL050_RXPARITY (1 << 2) 53#define PL050_KMIC (1 << 1) 54#define PL050_KMID (1 << 0) 55 |
56static const unsigned char pl050_id[] = 57{ 0x50, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; | 56static const unsigned char pl050_id[] = { 57 0x50, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 58}; |
58 59static void pl050_update(void *opaque, int level) 60{ 61 PL050State *s = (PL050State *)opaque; 62 int raise; 63 64 s->pending = level; 65 raise = (s->pending && (s->cr & 0x10) != 0) 66 || (s->cr & 0x08) != 0; 67 qemu_set_irq(s->irq, raise); 68} 69 70static uint64_t pl050_read(void *opaque, hwaddr offset, 71 unsigned size) 72{ 73 PL050State *s = (PL050State *)opaque; | 59 60static void pl050_update(void *opaque, int level) 61{ 62 PL050State *s = (PL050State *)opaque; 63 int raise; 64 65 s->pending = level; 66 raise = (s->pending && (s->cr & 0x10) != 0) 67 || (s->cr & 0x08) != 0; 68 qemu_set_irq(s->irq, raise); 69} 70 71static uint64_t pl050_read(void *opaque, hwaddr offset, 72 unsigned size) 73{ 74 PL050State *s = (PL050State *)opaque; |
74 if (offset >= 0xfe0 && offset < 0x1000) | 75 76 if (offset >= 0xfe0 && offset < 0x1000) { |
75 return pl050_id[(offset - 0xfe0) >> 2]; | 77 return pl050_id[(offset - 0xfe0) >> 2]; |
78 } |
|
76 77 switch (offset >> 2) { 78 case 0: /* KMICR */ 79 return s->cr; 80 case 1: /* KMISTAT */ 81 { 82 uint8_t val; 83 uint32_t stat; 84 85 val = s->last; 86 val = val ^ (val >> 4); 87 val = val ^ (val >> 2); 88 val = (val ^ (val >> 1)) & 1; 89 90 stat = PL050_TXEMPTY; | 79 80 switch (offset >> 2) { 81 case 0: /* KMICR */ 82 return s->cr; 83 case 1: /* KMISTAT */ 84 { 85 uint8_t val; 86 uint32_t stat; 87 88 val = s->last; 89 val = val ^ (val >> 4); 90 val = val ^ (val >> 2); 91 val = (val ^ (val >> 1)) & 1; 92 93 stat = PL050_TXEMPTY; |
91 if (val) | 94 if (val) { |
92 stat |= PL050_RXPARITY; | 95 stat |= PL050_RXPARITY; |
93 if (s->pending) | 96 } 97 if (s->pending) { |
94 stat |= PL050_RXFULL; | 98 stat |= PL050_RXFULL; |
99 } |
|
95 96 return stat; 97 } 98 case 2: /* KMIDATA */ | 100 101 return stat; 102 } 103 case 2: /* KMIDATA */ |
99 if (s->pending) | 104 if (s->pending) { |
100 s->last = ps2_read_data(s->dev); | 105 s->last = ps2_read_data(s->dev); |
106 } |
|
101 return s->last; 102 case 3: /* KMICLKDIV */ 103 return s->clk; 104 case 4: /* KMIIR */ 105 return s->pending | 2; 106 default: 107 qemu_log_mask(LOG_GUEST_ERROR, 108 "pl050_read: Bad offset %x\n", (int)offset); 109 return 0; 110 } 111} 112 113static void pl050_write(void *opaque, hwaddr offset, 114 uint64_t value, unsigned size) 115{ 116 PL050State *s = (PL050State *)opaque; | 107 return s->last; 108 case 3: /* KMICLKDIV */ 109 return s->clk; 110 case 4: /* KMIIR */ 111 return s->pending | 2; 112 default: 113 qemu_log_mask(LOG_GUEST_ERROR, 114 "pl050_read: Bad offset %x\n", (int)offset); 115 return 0; 116 } 117} 118 119static void pl050_write(void *opaque, hwaddr offset, 120 uint64_t value, unsigned size) 121{ 122 PL050State *s = (PL050State *)opaque; |
123 |
|
117 switch (offset >> 2) { 118 case 0: /* KMICR */ 119 s->cr = value; 120 pl050_update(s, s->pending); 121 /* ??? Need to implement the enable/disable bit. */ 122 break; 123 case 2: /* KMIDATA */ 124 /* ??? This should toggle the TX interrupt line. */ --- 86 unchanged lines hidden --- | 124 switch (offset >> 2) { 125 case 0: /* KMICR */ 126 s->cr = value; 127 pl050_update(s, s->pending); 128 /* ??? Need to implement the enable/disable bit. */ 129 break; 130 case 2: /* KMIDATA */ 131 /* ??? This should toggle the TX interrupt line. */ --- 86 unchanged lines hidden --- |