/*
* QEMU generic PPC hardware System Emulator
*
- * Copyright (c) 2003-2004 Jocelyn Mayer
+ * Copyright (c) 2003-2007 Jocelyn Mayer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
{
/* TB time in tb periods */
return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset,
- tb_env->tb_freq, ticks_per_sec);
+ tb_env->tb_freq, ticks_per_sec);
}
uint32_t cpu_ppc_load_tbl (CPUState *env)
tb = cpu_ppc_get_tb(tb_env);
#ifdef DEBUG_TB
{
- static int last_time;
- int now;
- now = time(NULL);
- if (last_time != now) {
- last_time = now;
- printf("%s: tb=0x%016lx %d %08lx\n",
- __func__, tb, now, tb_env->tb_offset);
- }
+ static int last_time;
+ int now;
+ now = time(NULL);
+ if (last_time != now) {
+ last_time = now;
+ printf("%s: tb=0x%016lx %d %08lx\n",
+ __func__, tb, now, tb_env->tb_offset);
+ }
}
#endif
#ifdef DEBUG_TB
printf("%s: tb=0x%016lx\n", __func__, tb);
#endif
+
return tb >> 32;
}
#if defined(DEBUG_TB)
printf("%s: 0x%08x\n", __func__, decr);
#endif
+
return decr;
}
if (is_excp)
next += tb_env->decr_next - now;
if (next == now)
- next++;
+ next++;
tb_env->decr_next = next;
/* Adjust timer */
qemu_mod_timer(tb_env->decr_timer, next);
* raise an exception.
*/
if ((value & 0x80000000) && !(decr & 0x80000000))
- cpu_ppc_decr_excp(env);
+ cpu_ppc_decr_excp(env);
}
void cpu_ppc_store_decr (CPUState *env, uint32_t value)
return NULL;
env->tb_env = tb_env;
if (tb_env->tb_freq == 0 || 1) {
- tb_env->tb_freq = freq;
- /* Create new timer */
- tb_env->decr_timer =
+ tb_env->tb_freq = freq;
+ /* Create new timer */
+ tb_env->decr_timer =
qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
- /* There is a bug in 2.4 kernels:
- * if a decrementer exception is pending when it enables msr_ee,
- * it's not ready to handle it...
- */
- _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
+ /* There is a bug in Linux 2.4 kernels:
+ * if a decrementer exception is pending when it enables msr_ee,
+ * it's not ready to handle it...
+ */
+ _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
}
return tb_env;
}
-#if 0
-/*****************************************************************************/
-/* Handle system reset (for now, just stop emulation) */
-void cpu_ppc_reset (CPUState *env)
+/* Specific helpers for POWER & PowerPC 601 RTC */
+ppc_tb_t *cpu_ppc601_rtc_init (CPUState *env)
{
- printf("Reset asked... Stop emulation\n");
- abort();
+ return cpu_ppc_tb_init(env, 7812500);
}
-#endif
-static void PPC_io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
+__attribute__ (( alias ("cpu_ppc_store_tbu") ));
+
+uint32_t cpu_ppc601_load_rtcu (CPUState *env)
+__attribute__ (( alias ("cpu_ppc_load_tbu") ));
+
+void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
{
- cpu_outb(NULL, addr & 0xffff, value);
+ cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
}
-static uint32_t PPC_io_readb (void *opaque, target_phys_addr_t addr)
+uint32_t cpu_ppc601_load_rtcl (CPUState *env)
{
- uint32_t ret = cpu_inb(NULL, addr & 0xffff);
- return ret;
+ return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
}
-static void PPC_io_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+/* Embedded PowerPC timers */
+target_ulong load_40x_pit (CPUState *env)
{
-#ifdef TARGET_WORDS_BIGENDIAN
- value = bswap16(value);
-#endif
- cpu_outw(NULL, addr & 0xffff, value);
+ /* XXX: TODO */
+ return 0;
}
-static uint32_t PPC_io_readw (void *opaque, target_phys_addr_t addr)
+void store_40x_pit (CPUState *env, target_ulong val)
{
- uint32_t ret = cpu_inw(NULL, addr & 0xffff);
-#ifdef TARGET_WORDS_BIGENDIAN
- ret = bswap16(ret);
-#endif
- return ret;
+ /* XXX: TODO */
}
-static void PPC_io_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+void store_booke_tcr (CPUState *env, target_ulong val)
{
-#ifdef TARGET_WORDS_BIGENDIAN
- value = bswap32(value);
-#endif
- cpu_outl(NULL, addr & 0xffff, value);
+ /* XXX: TODO */
}
-static uint32_t PPC_io_readl (void *opaque, target_phys_addr_t addr)
+void store_booke_tsr (CPUState *env, target_ulong val)
{
- uint32_t ret = cpu_inl(NULL, addr & 0xffff);
-
-#ifdef TARGET_WORDS_BIGENDIAN
- ret = bswap32(ret);
-#endif
- return ret;
+ /* XXX: TODO */
}
-CPUWriteMemoryFunc *PPC_io_write[] = {
- &PPC_io_writeb,
- &PPC_io_writew,
- &PPC_io_writel,
-};
-
-CPUReadMemoryFunc *PPC_io_read[] = {
- &PPC_io_readb,
- &PPC_io_readw,
- &PPC_io_readl,
-};
+#if 0
+/*****************************************************************************/
+/* Handle system reset (for now, just stop emulation) */
+void cpu_ppc_reset (CPUState *env)
+{
+ printf("Reset asked... Stop emulation\n");
+ abort();
+}
+#endif
/*****************************************************************************/
/* Debug port */
/* NVRAM helpers */
void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
{
- m48t59_set_addr(nvram, addr);
- m48t59_write(nvram, value);
+ m48t59_write(nvram, addr, value);
}
uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
{
- m48t59_set_addr(nvram, addr);
- return m48t59_read(nvram);
+ return m48t59_read(nvram, addr);
}
void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
{
- m48t59_set_addr(nvram, addr);
- m48t59_write(nvram, value >> 8);
- m48t59_set_addr(nvram, addr + 1);
- m48t59_write(nvram, value & 0xFF);
+ m48t59_write(nvram, addr, value >> 8);
+ m48t59_write(nvram, addr + 1, value & 0xFF);
}
uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
{
uint16_t tmp;
- m48t59_set_addr(nvram, addr);
- tmp = m48t59_read(nvram) << 8;
- m48t59_set_addr(nvram, addr + 1);
- tmp |= m48t59_read(nvram);
-
+ tmp = m48t59_read(nvram, addr) << 8;
+ tmp |= m48t59_read(nvram, addr + 1);
return tmp;
}
void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
{
- m48t59_set_addr(nvram, addr);
- m48t59_write(nvram, value >> 24);
- m48t59_set_addr(nvram, addr + 1);
- m48t59_write(nvram, (value >> 16) & 0xFF);
- m48t59_set_addr(nvram, addr + 2);
- m48t59_write(nvram, (value >> 8) & 0xFF);
- m48t59_set_addr(nvram, addr + 3);
- m48t59_write(nvram, value & 0xFF);
+ m48t59_write(nvram, addr, value >> 24);
+ m48t59_write(nvram, addr + 1, (value >> 16) & 0xFF);
+ m48t59_write(nvram, addr + 2, (value >> 8) & 0xFF);
+ m48t59_write(nvram, addr + 3, value & 0xFF);
}
uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
{
uint32_t tmp;
- m48t59_set_addr(nvram, addr);
- tmp = m48t59_read(nvram) << 24;
- m48t59_set_addr(nvram, addr + 1);
- tmp |= m48t59_read(nvram) << 16;
- m48t59_set_addr(nvram, addr + 2);
- tmp |= m48t59_read(nvram) << 8;
- m48t59_set_addr(nvram, addr + 3);
- tmp |= m48t59_read(nvram);
+ tmp = m48t59_read(nvram, addr) << 24;
+ tmp |= m48t59_read(nvram, addr + 1) << 16;
+ tmp |= m48t59_read(nvram, addr + 2) << 8;
+ tmp |= m48t59_read(nvram, addr + 3);
return tmp;
}
int i;
for (i = 0; i < max && str[i] != '\0'; i++) {
- m48t59_set_addr(nvram, addr + i);
- m48t59_write(nvram, str[i]);
+ m48t59_write(nvram, addr + i, str[i]);
}
- m48t59_set_addr(nvram, addr + max - 1);
- m48t59_write(nvram, '\0');
+ m48t59_write(nvram, addr + max - 1, '\0');
}
int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
odd = count & 1;
count &= ~1;
for (i = 0; i != count; i++) {
- crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
+ crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
}
if (odd) {
- crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
+ crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
}
return crc;