1 /* Copyright (C) 2007-2008 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 #include "qemu-common.h" 13 #include "qemu-timer.h" 14 #include "cpu.h" 15 #include "arm_pic.h" 16 #include "goldfish_device.h" 17 #include "hw/hw.h" 18 19 enum { 20 TIMER_TIME_LOW = 0x00, // get low bits of current time and update TIMER_TIME_HIGH 21 TIMER_TIME_HIGH = 0x04, // get high bits of time at last TIMER_TIME_LOW read 22 TIMER_ALARM_LOW = 0x08, // set low bits of alarm and activate it 23 TIMER_ALARM_HIGH = 0x0c, // set high bits of next alarm 24 TIMER_CLEAR_INTERRUPT = 0x10, 25 TIMER_CLEAR_ALARM = 0x14 26 }; 27 28 struct timer_state { 29 struct goldfish_device dev; 30 uint32_t alarm_low_ns; 31 int32_t alarm_high_ns; 32 int64_t now_ns; 33 int armed; 34 QEMUTimer *timer; 35 }; 36 37 #define GOLDFISH_TIMER_SAVE_VERSION 1 38 39 static void goldfish_timer_save(QEMUFile* f, void* opaque) 40 { 41 struct timer_state* s = opaque; 42 43 qemu_put_be64(f, s->now_ns); /* in case the kernel is in the middle of a timer read */ 44 qemu_put_byte(f, s->armed); 45 if (s->armed) { 46 int64_t now_ns = qemu_get_clock_ns(vm_clock); 47 int64_t alarm_ns = (s->alarm_low_ns | (int64_t)s->alarm_high_ns << 32); 48 qemu_put_be64(f, alarm_ns - now_ns); 49 } 50 } 51 52 static int goldfish_timer_load(QEMUFile* f, void* opaque, int version_id) 53 { 54 struct timer_state* s = opaque; 55 56 if (version_id != GOLDFISH_TIMER_SAVE_VERSION) 57 return -1; 58 59 s->now_ns = qemu_get_be64(f); 60 s->armed = qemu_get_byte(f); 61 if (s->armed) { 62 int64_t now_tks = qemu_get_clock(vm_clock); 63 int64_t diff_tks = qemu_get_be64(f); 64 int64_t alarm_tks = now_tks + diff_tks; 65 66 if (alarm_tks <= now_tks) { 67 goldfish_device_set_irq(&s->dev, 0, 1); 68 s->armed = 0; 69 } else { 70 qemu_mod_timer(s->timer, alarm_tks); 71 } 72 } 73 return 0; 74 } 75 76 static uint32_t goldfish_timer_read(void *opaque, target_phys_addr_t offset) 77 { 78 struct timer_state *s = (struct timer_state *)opaque; 79 switch(offset) { 80 case TIMER_TIME_LOW: 81 s->now_ns = qemu_get_clock_ns(vm_clock); 82 return s->now_ns; 83 case TIMER_TIME_HIGH: 84 return s->now_ns >> 32; 85 default: 86 cpu_abort (cpu_single_env, "goldfish_timer_read: Bad offset %x\n", offset); 87 return 0; 88 } 89 } 90 91 static void goldfish_timer_write(void *opaque, target_phys_addr_t offset, uint32_t value_ns) 92 { 93 struct timer_state *s = (struct timer_state *)opaque; 94 int64_t alarm_ns, now_ns; 95 switch(offset) { 96 case TIMER_ALARM_LOW: 97 s->alarm_low_ns = value_ns; 98 alarm_ns = (s->alarm_low_ns | (int64_t)s->alarm_high_ns << 32); 99 now_ns = qemu_get_clock_ns(vm_clock); 100 if (alarm_ns <= now_ns) { 101 goldfish_device_set_irq(&s->dev, 0, 1); 102 } else { 103 qemu_mod_timer(s->timer, alarm_ns); 104 s->armed = 1; 105 } 106 break; 107 case TIMER_ALARM_HIGH: 108 s->alarm_high_ns = value_ns; 109 break; 110 case TIMER_CLEAR_ALARM: 111 qemu_del_timer(s->timer); 112 s->armed = 0; 113 /* fall through */ 114 case TIMER_CLEAR_INTERRUPT: 115 goldfish_device_set_irq(&s->dev, 0, 0); 116 break; 117 default: 118 cpu_abort (cpu_single_env, "goldfish_timer_write: Bad offset %x\n", offset); 119 } 120 } 121 122 static void goldfish_timer_tick(void *opaque) 123 { 124 struct timer_state *s = (struct timer_state *)opaque; 125 126 s->armed = 0; 127 goldfish_device_set_irq(&s->dev, 0, 1); 128 } 129 130 struct rtc_state { 131 struct goldfish_device dev; 132 uint32_t alarm_low; 133 int32_t alarm_high; 134 int64_t now; 135 }; 136 137 /* we save the RTC for the case where the kernel is in the middle of a rtc_read 138 * (i.e. it has read the low 32-bit of s->now, but not the high 32-bits yet */ 139 #define GOLDFISH_RTC_SAVE_VERSION 1 140 141 static void goldfish_rtc_save(QEMUFile* f, void* opaque) 142 { 143 struct rtc_state* s = opaque; 144 145 qemu_put_be64(f, s->now); 146 } 147 148 static int goldfish_rtc_load(QEMUFile* f, void* opaque, int version_id) 149 { 150 struct rtc_state* s = opaque; 151 152 if (version_id != GOLDFISH_RTC_SAVE_VERSION) 153 return -1; 154 155 /* this is an old value that is not correct. but that's ok anyway */ 156 s->now = qemu_get_be64(f); 157 return 0; 158 } 159 160 static uint32_t goldfish_rtc_read(void *opaque, target_phys_addr_t offset) 161 { 162 struct rtc_state *s = (struct rtc_state *)opaque; 163 switch(offset) { 164 case 0x0: 165 s->now = (int64_t)time(NULL) * 1000000000; 166 return s->now; 167 case 0x4: 168 return s->now >> 32; 169 default: 170 cpu_abort (cpu_single_env, "goldfish_rtc_read: Bad offset %x\n", offset); 171 return 0; 172 } 173 } 174 175 static void goldfish_rtc_write(void *opaque, target_phys_addr_t offset, uint32_t value) 176 { 177 struct rtc_state *s = (struct rtc_state *)opaque; 178 int64_t alarm; 179 switch(offset) { 180 case 0x8: 181 s->alarm_low = value; 182 alarm = s->alarm_low | (int64_t)s->alarm_high << 32; 183 //printf("next alarm at %lld, tps %lld\n", alarm, ticks_per_sec); 184 //qemu_mod_timer(s->timer, alarm); 185 break; 186 case 0xc: 187 s->alarm_high = value; 188 //printf("alarm_high %d\n", s->alarm_high); 189 break; 190 case 0x10: 191 goldfish_device_set_irq(&s->dev, 0, 0); 192 break; 193 default: 194 cpu_abort (cpu_single_env, "goldfish_rtc_write: Bad offset %x\n", offset); 195 } 196 } 197 198 static struct timer_state timer_state = { 199 .dev = { 200 .name = "goldfish_timer", 201 .id = -1, 202 .size = 0x1000, 203 .irq_count = 1, 204 } 205 }; 206 207 static struct timer_state rtc_state = { 208 .dev = { 209 .name = "goldfish_rtc", 210 .id = -1, 211 .size = 0x1000, 212 .irq_count = 1, 213 } 214 }; 215 216 static CPUReadMemoryFunc *goldfish_timer_readfn[] = { 217 goldfish_timer_read, 218 goldfish_timer_read, 219 goldfish_timer_read 220 }; 221 222 static CPUWriteMemoryFunc *goldfish_timer_writefn[] = { 223 goldfish_timer_write, 224 goldfish_timer_write, 225 goldfish_timer_write 226 }; 227 228 static CPUReadMemoryFunc *goldfish_rtc_readfn[] = { 229 goldfish_rtc_read, 230 goldfish_rtc_read, 231 goldfish_rtc_read 232 }; 233 234 static CPUWriteMemoryFunc *goldfish_rtc_writefn[] = { 235 goldfish_rtc_write, 236 goldfish_rtc_write, 237 goldfish_rtc_write 238 }; 239 240 void goldfish_timer_and_rtc_init(uint32_t timerbase, int timerirq) 241 { 242 timer_state.dev.base = timerbase; 243 timer_state.dev.irq = timerirq; 244 timer_state.timer = qemu_new_timer_ns(vm_clock, goldfish_timer_tick, &timer_state); 245 goldfish_device_add(&timer_state.dev, goldfish_timer_readfn, goldfish_timer_writefn, &timer_state); 246 register_savevm( "goldfish_timer", 0, GOLDFISH_TIMER_SAVE_VERSION, 247 goldfish_timer_save, goldfish_timer_load, &timer_state); 248 249 goldfish_device_add(&rtc_state.dev, goldfish_rtc_readfn, goldfish_rtc_writefn, &rtc_state); 250 register_savevm( "goldfish_rtc", 0, GOLDFISH_RTC_SAVE_VERSION, 251 goldfish_rtc_save, goldfish_rtc_load, &rtc_state); 252 } 253 254