ppc patch queue -2015-11-12
Highlights: - A number of fixes for MacOS 9 compatibility based on the old MOL (Mac-On-Linux) code and a GSoC project. - Cleaner and more general way of handling register access from the monitor -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWRBaWAAoJEGw4ysog2bOS2+IP/R4yoYmSBjb36zs6lardzAdl rKbqXrCev60MIDprXwu+6ilWenAl8tMQyv841DR1/u2drwnmEGizuGzg2rjCfigS MlXuNyNKVhkrS8+KNuI88W8JTfLDiSr+uL6LoRPnDU2pWdwrbFNABTvDS2qQ3ENj zS8LyGkqtfyFFuJtjudCNq0bO+e4DUn0nXtGjERb5zUUIa6O7O5zGTHmY7+WzDR9 56wldCnxgFYu6Xguzz/ZBlImcTN4lhsNd0XnfK2GhM3l7jnS57BjolIVQvSDq9ly zf8HfC/E6eEKS3bgpslrGXUOfcrBYnmmlXUPWYEK8WnozEQjoE0vJolyMKTLwJ+7 PX6WWwMrwN3VCfzmX4Qe/QXl1xv8RhWvChfe41LbbS4XcD+hQUfl3O6B1MxVobsZ dHNGh0BnoPwIq4kjNPCM8F+lCbm24irsF+OtsjBMzZbZc6aJkKq6URrFNJlL6Pua prMYgz9AIPrp8gR+OXL2SgNKXt3iMd1WT9fG/n523KSp+zE+/dYQBiIJuxZX4uP4 u46AHpfrGd+v4nXuN85FvHROCwylEVMLTSF58jYVWZmrY3hOfmiXWngo5wm1lOLi 7cvpZEJ2BUoWOGMDgeg1fSqSOvg1UA0Hb5Chykb083tBZCnTQkukBtcTegd93mXe RDVuhdeI+zlI4sE1rMpn =ayjU -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dgibson/tags/ppc-next-20151112' into staging ppc patch queue -2015-11-12 Highlights: - A number of fixes for MacOS 9 compatibility based on the old MOL (Mac-On-Linux) code and a GSoC project. - Cleaner and more general way of handling register access from the monitor # gpg: Signature made Thu 12 Nov 2015 04:33:26 GMT using RSA key ID 20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-next-20151112: monitor/target-ppc: Define target_get_monitor_def cuda.c: add delay to setting of SR_INT bit cuda.c: fix T2 timer and enable its interrupt cuda.c: rename get_counter() state variable from s to ti for consistency cuda.c: refactor get_tb() so that the time can be passed in cuda.c: add defines for CUDA registers cuda.c: fix CUDA SR interrupt clearing cuda.c: implement dummy IIC access commands cuda.c: implement simple CUDA_GET_6805_ADDR command cuda.c: fix CUDA_PACKET response packet format cuda.c: fix CUDA ADB error packet format PPC: mac99: Always add USB controller PPC: Fix lswx bounds checks PPC: Allow Rc bit to be set on mtspr Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
df1ac44e9f
@ -57,6 +57,8 @@
|
||||
#define IER_SET 0x80 /* set bits in IER */
|
||||
#define IER_CLR 0 /* clear bits in IER */
|
||||
#define SR_INT 0x04 /* Shift register full/empty */
|
||||
#define SR_DATA_INT 0x08
|
||||
#define SR_CLOCK_INT 0x10
|
||||
#define T1_INT 0x40 /* Timer 1 interrupt */
|
||||
#define T2_INT 0x20 /* Timer 2 interrupt */
|
||||
|
||||
@ -108,6 +110,24 @@
|
||||
/* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
|
||||
#define RTC_OFFSET 2082844800
|
||||
|
||||
/* CUDA registers */
|
||||
#define CUDA_REG_B 0x00
|
||||
#define CUDA_REG_A 0x01
|
||||
#define CUDA_REG_DIRB 0x02
|
||||
#define CUDA_REG_DIRA 0x03
|
||||
#define CUDA_REG_T1CL 0x04
|
||||
#define CUDA_REG_T1CH 0x05
|
||||
#define CUDA_REG_T1LL 0x06
|
||||
#define CUDA_REG_T1LH 0x07
|
||||
#define CUDA_REG_T2CL 0x08
|
||||
#define CUDA_REG_T2CH 0x09
|
||||
#define CUDA_REG_SR 0x0a
|
||||
#define CUDA_REG_ACR 0x0b
|
||||
#define CUDA_REG_PCR 0x0c
|
||||
#define CUDA_REG_IFR 0x0d
|
||||
#define CUDA_REG_IER 0x0e
|
||||
#define CUDA_REG_ANH 0x0f
|
||||
|
||||
static void cuda_update(CUDAState *s);
|
||||
static void cuda_receive_packet_from_host(CUDAState *s,
|
||||
const uint8_t *data, int len);
|
||||
@ -116,47 +136,48 @@ static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
|
||||
|
||||
static void cuda_update_irq(CUDAState *s)
|
||||
{
|
||||
if (s->ifr & s->ier & (SR_INT | T1_INT)) {
|
||||
if (s->ifr & s->ier & (SR_INT | T1_INT | T2_INT)) {
|
||||
qemu_irq_raise(s->irq);
|
||||
} else {
|
||||
qemu_irq_lower(s->irq);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t get_tb(uint64_t freq)
|
||||
static uint64_t get_tb(uint64_t time, uint64_t freq)
|
||||
{
|
||||
return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
|
||||
freq, get_ticks_per_sec());
|
||||
return muldiv64(time, freq, get_ticks_per_sec());
|
||||
}
|
||||
|
||||
static unsigned int get_counter(CUDATimer *s)
|
||||
static unsigned int get_counter(CUDATimer *ti)
|
||||
{
|
||||
int64_t d;
|
||||
unsigned int counter;
|
||||
uint64_t tb_diff;
|
||||
uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
|
||||
/* Reverse of the tb calculation algorithm that Mac OS X uses on bootup. */
|
||||
tb_diff = get_tb(s->frequency) - s->load_time;
|
||||
d = (tb_diff * 0xBF401675E5DULL) / (s->frequency << 24);
|
||||
tb_diff = get_tb(current_time, ti->frequency) - ti->load_time;
|
||||
d = (tb_diff * 0xBF401675E5DULL) / (ti->frequency << 24);
|
||||
|
||||
if (s->index == 0) {
|
||||
if (ti->index == 0) {
|
||||
/* the timer goes down from latch to -1 (period of latch + 2) */
|
||||
if (d <= (s->counter_value + 1)) {
|
||||
counter = (s->counter_value - d) & 0xffff;
|
||||
if (d <= (ti->counter_value + 1)) {
|
||||
counter = (ti->counter_value - d) & 0xffff;
|
||||
} else {
|
||||
counter = (d - (s->counter_value + 1)) % (s->latch + 2);
|
||||
counter = (s->latch - counter) & 0xffff;
|
||||
counter = (d - (ti->counter_value + 1)) % (ti->latch + 2);
|
||||
counter = (ti->latch - counter) & 0xffff;
|
||||
}
|
||||
} else {
|
||||
counter = (s->counter_value - d) & 0xffff;
|
||||
counter = (ti->counter_value - d) & 0xffff;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
|
||||
{
|
||||
CUDA_DPRINTF("T%d.counter=%d\n", 1 + (ti->timer == NULL), val);
|
||||
ti->load_time = get_tb(s->frequency);
|
||||
CUDA_DPRINTF("T%d.counter=%d\n", 1 + ti->index, val);
|
||||
ti->load_time = get_tb(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
|
||||
s->frequency);
|
||||
ti->counter_value = val;
|
||||
cuda_timer_update(s, ti, ti->load_time);
|
||||
}
|
||||
@ -199,7 +220,7 @@ static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
|
||||
{
|
||||
if (!ti->timer)
|
||||
return;
|
||||
if ((s->acr & T1MODE) != T1MODE_CONT) {
|
||||
if (ti->index == 0 && (s->acr & T1MODE) != T1MODE_CONT) {
|
||||
timer_del(ti->timer);
|
||||
} else {
|
||||
ti->next_irq_time = get_next_irq_time(ti, current_time);
|
||||
@ -217,6 +238,41 @@ static void cuda_timer1(void *opaque)
|
||||
cuda_update_irq(s);
|
||||
}
|
||||
|
||||
static void cuda_timer2(void *opaque)
|
||||
{
|
||||
CUDAState *s = opaque;
|
||||
CUDATimer *ti = &s->timers[1];
|
||||
|
||||
cuda_timer_update(s, ti, ti->next_irq_time);
|
||||
s->ifr |= T2_INT;
|
||||
cuda_update_irq(s);
|
||||
}
|
||||
|
||||
static void cuda_set_sr_int(void *opaque)
|
||||
{
|
||||
CUDAState *s = opaque;
|
||||
|
||||
CUDA_DPRINTF("CUDA: %s:%d\n", __func__, __LINE__);
|
||||
s->ifr |= SR_INT;
|
||||
cuda_update_irq(s);
|
||||
}
|
||||
|
||||
static void cuda_delay_set_sr_int(CUDAState *s)
|
||||
{
|
||||
int64_t expire;
|
||||
|
||||
if (s->dirb == 0xff) {
|
||||
/* Not in Mac OS, fire the IRQ directly */
|
||||
cuda_set_sr_int(s);
|
||||
return;
|
||||
}
|
||||
|
||||
CUDA_DPRINTF("CUDA: %s:%d\n", __func__, __LINE__);
|
||||
|
||||
expire = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 300 * SCALE_US;
|
||||
timer_mod(s->sr_delay_timer, expire);
|
||||
}
|
||||
|
||||
static uint32_t cuda_readb(void *opaque, hwaddr addr)
|
||||
{
|
||||
CUDAState *s = opaque;
|
||||
@ -224,66 +280,68 @@ static uint32_t cuda_readb(void *opaque, hwaddr addr)
|
||||
|
||||
addr = (addr >> 9) & 0xf;
|
||||
switch(addr) {
|
||||
case 0:
|
||||
case CUDA_REG_B:
|
||||
val = s->b;
|
||||
break;
|
||||
case 1:
|
||||
case CUDA_REG_A:
|
||||
val = s->a;
|
||||
break;
|
||||
case 2:
|
||||
case CUDA_REG_DIRB:
|
||||
val = s->dirb;
|
||||
break;
|
||||
case 3:
|
||||
case CUDA_REG_DIRA:
|
||||
val = s->dira;
|
||||
break;
|
||||
case 4:
|
||||
case CUDA_REG_T1CL:
|
||||
val = get_counter(&s->timers[0]) & 0xff;
|
||||
s->ifr &= ~T1_INT;
|
||||
cuda_update_irq(s);
|
||||
break;
|
||||
case 5:
|
||||
case CUDA_REG_T1CH:
|
||||
val = get_counter(&s->timers[0]) >> 8;
|
||||
cuda_update_irq(s);
|
||||
break;
|
||||
case 6:
|
||||
case CUDA_REG_T1LL:
|
||||
val = s->timers[0].latch & 0xff;
|
||||
break;
|
||||
case 7:
|
||||
case CUDA_REG_T1LH:
|
||||
/* XXX: check this */
|
||||
val = (s->timers[0].latch >> 8) & 0xff;
|
||||
break;
|
||||
case 8:
|
||||
case CUDA_REG_T2CL:
|
||||
val = get_counter(&s->timers[1]) & 0xff;
|
||||
s->ifr &= ~T2_INT;
|
||||
break;
|
||||
case 9:
|
||||
val = get_counter(&s->timers[1]) >> 8;
|
||||
break;
|
||||
case 10:
|
||||
val = s->sr;
|
||||
s->ifr &= ~SR_INT;
|
||||
cuda_update_irq(s);
|
||||
break;
|
||||
case 11:
|
||||
case CUDA_REG_T2CH:
|
||||
val = get_counter(&s->timers[1]) >> 8;
|
||||
break;
|
||||
case CUDA_REG_SR:
|
||||
val = s->sr;
|
||||
s->ifr &= ~(SR_INT | SR_CLOCK_INT | SR_DATA_INT);
|
||||
cuda_update_irq(s);
|
||||
break;
|
||||
case CUDA_REG_ACR:
|
||||
val = s->acr;
|
||||
break;
|
||||
case 12:
|
||||
case CUDA_REG_PCR:
|
||||
val = s->pcr;
|
||||
break;
|
||||
case 13:
|
||||
case CUDA_REG_IFR:
|
||||
val = s->ifr;
|
||||
if (s->ifr & s->ier)
|
||||
if (s->ifr & s->ier) {
|
||||
val |= 0x80;
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
case CUDA_REG_IER:
|
||||
val = s->ier | 0x80;
|
||||
break;
|
||||
default:
|
||||
case 15:
|
||||
case CUDA_REG_ANH:
|
||||
val = s->anh;
|
||||
break;
|
||||
}
|
||||
if (addr != 13 || val != 0) {
|
||||
if (addr != CUDA_REG_IFR || val != 0) {
|
||||
CUDA_DPRINTF("read: reg=0x%x val=%02x\n", (int)addr, val);
|
||||
}
|
||||
|
||||
@ -298,61 +356,65 @@ static void cuda_writeb(void *opaque, hwaddr addr, uint32_t val)
|
||||
CUDA_DPRINTF("write: reg=0x%x val=%02x\n", (int)addr, val);
|
||||
|
||||
switch(addr) {
|
||||
case 0:
|
||||
case CUDA_REG_B:
|
||||
s->b = val;
|
||||
cuda_update(s);
|
||||
break;
|
||||
case 1:
|
||||
case CUDA_REG_A:
|
||||
s->a = val;
|
||||
break;
|
||||
case 2:
|
||||
case CUDA_REG_DIRB:
|
||||
s->dirb = val;
|
||||
break;
|
||||
case 3:
|
||||
case CUDA_REG_DIRA:
|
||||
s->dira = val;
|
||||
break;
|
||||
case 4:
|
||||
case CUDA_REG_T1CL:
|
||||
s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
|
||||
cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
break;
|
||||
case 5:
|
||||
case CUDA_REG_T1CH:
|
||||
s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
|
||||
s->ifr &= ~T1_INT;
|
||||
set_counter(s, &s->timers[0], s->timers[0].latch);
|
||||
break;
|
||||
case 6:
|
||||
case CUDA_REG_T1LL:
|
||||
s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
|
||||
cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
break;
|
||||
case 7:
|
||||
case CUDA_REG_T1LH:
|
||||
s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
|
||||
s->ifr &= ~T1_INT;
|
||||
cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
break;
|
||||
case 8:
|
||||
s->timers[1].latch = val;
|
||||
set_counter(s, &s->timers[1], val);
|
||||
case CUDA_REG_T2CL:
|
||||
s->timers[1].latch = (s->timers[1].latch & 0xff00) | val;
|
||||
break;
|
||||
case 9:
|
||||
set_counter(s, &s->timers[1], (val << 8) | s->timers[1].latch);
|
||||
case CUDA_REG_T2CH:
|
||||
/* To ensure T2 generates an interrupt on zero crossing with the
|
||||
common timer code, write the value directly from the latch to
|
||||
the counter */
|
||||
s->timers[1].latch = (s->timers[1].latch & 0xff) | (val << 8);
|
||||
s->ifr &= ~T2_INT;
|
||||
set_counter(s, &s->timers[1], s->timers[1].latch);
|
||||
break;
|
||||
case 10:
|
||||
case CUDA_REG_SR:
|
||||
s->sr = val;
|
||||
break;
|
||||
case 11:
|
||||
case CUDA_REG_ACR:
|
||||
s->acr = val;
|
||||
cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
cuda_update(s);
|
||||
break;
|
||||
case 12:
|
||||
case CUDA_REG_PCR:
|
||||
s->pcr = val;
|
||||
break;
|
||||
case 13:
|
||||
case CUDA_REG_IFR:
|
||||
/* reset bits */
|
||||
s->ifr &= ~val;
|
||||
cuda_update_irq(s);
|
||||
break;
|
||||
case 14:
|
||||
case CUDA_REG_IER:
|
||||
if (val & IER_SET) {
|
||||
/* set bits */
|
||||
s->ier |= val & 0x7f;
|
||||
@ -363,7 +425,7 @@ static void cuda_writeb(void *opaque, hwaddr addr, uint32_t val)
|
||||
cuda_update_irq(s);
|
||||
break;
|
||||
default:
|
||||
case 15:
|
||||
case CUDA_REG_ANH:
|
||||
s->anh = val;
|
||||
break;
|
||||
}
|
||||
@ -384,8 +446,7 @@ static void cuda_update(CUDAState *s)
|
||||
if (s->data_out_index < sizeof(s->data_out)) {
|
||||
CUDA_DPRINTF("send: %02x\n", s->sr);
|
||||
s->data_out[s->data_out_index++] = s->sr;
|
||||
s->ifr |= SR_INT;
|
||||
cuda_update_irq(s);
|
||||
cuda_delay_set_sr_int(s);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -398,8 +459,7 @@ static void cuda_update(CUDAState *s)
|
||||
if (s->data_in_index >= s->data_in_size) {
|
||||
s->b = (s->b | TREQ);
|
||||
}
|
||||
s->ifr |= SR_INT;
|
||||
cuda_update_irq(s);
|
||||
cuda_delay_set_sr_int(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -411,15 +471,13 @@ static void cuda_update(CUDAState *s)
|
||||
s->b = (s->b | TREQ);
|
||||
else
|
||||
s->b = (s->b & ~TREQ);
|
||||
s->ifr |= SR_INT;
|
||||
cuda_update_irq(s);
|
||||
cuda_delay_set_sr_int(s);
|
||||
} else {
|
||||
if (!(s->last_b & TIP)) {
|
||||
/* handle end of host to cuda transfer */
|
||||
packet_received = (s->data_out_index > 0);
|
||||
/* always an IRQ at the end of transfer */
|
||||
s->ifr |= SR_INT;
|
||||
cuda_update_irq(s);
|
||||
cuda_delay_set_sr_int(s);
|
||||
}
|
||||
/* signal if there is data to read */
|
||||
if (s->data_in_index < s->data_in_size) {
|
||||
@ -456,8 +514,7 @@ static void cuda_send_packet_to_host(CUDAState *s,
|
||||
s->data_in_size = len;
|
||||
s->data_in_index = 0;
|
||||
cuda_update(s);
|
||||
s->ifr |= SR_INT;
|
||||
cuda_update_irq(s);
|
||||
cuda_delay_set_sr_int(s);
|
||||
}
|
||||
|
||||
static void cuda_adb_poll(void *opaque)
|
||||
@ -480,7 +537,7 @@ static void cuda_adb_poll(void *opaque)
|
||||
static void cuda_receive_packet(CUDAState *s,
|
||||
const uint8_t *data, int len)
|
||||
{
|
||||
uint8_t obuf[16];
|
||||
uint8_t obuf[16] = { CUDA_PACKET, 0, data[0] };
|
||||
int autopoll;
|
||||
uint32_t ti;
|
||||
|
||||
@ -497,23 +554,18 @@ static void cuda_receive_packet(CUDAState *s,
|
||||
timer_del(s->adb_poll_timer);
|
||||
}
|
||||
}
|
||||
obuf[0] = CUDA_PACKET;
|
||||
obuf[1] = data[1];
|
||||
cuda_send_packet_to_host(s, obuf, 2);
|
||||
cuda_send_packet_to_host(s, obuf, 3);
|
||||
break;
|
||||
case CUDA_GET_6805_ADDR:
|
||||
cuda_send_packet_to_host(s, obuf, 3);
|
||||
break;
|
||||
case CUDA_SET_TIME:
|
||||
ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + (((uint32_t)data[3]) << 8) + data[4];
|
||||
s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
|
||||
obuf[0] = CUDA_PACKET;
|
||||
obuf[1] = 0;
|
||||
obuf[2] = 0;
|
||||
cuda_send_packet_to_host(s, obuf, 3);
|
||||
break;
|
||||
case CUDA_GET_TIME:
|
||||
ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
|
||||
obuf[0] = CUDA_PACKET;
|
||||
obuf[1] = 0;
|
||||
obuf[2] = 0;
|
||||
obuf[3] = ti >> 24;
|
||||
obuf[4] = ti >> 16;
|
||||
obuf[5] = ti >> 8;
|
||||
@ -524,22 +576,34 @@ static void cuda_receive_packet(CUDAState *s,
|
||||
case CUDA_SET_DEVICE_LIST:
|
||||
case CUDA_SET_AUTO_RATE:
|
||||
case CUDA_SET_POWER_MESSAGES:
|
||||
obuf[0] = CUDA_PACKET;
|
||||
obuf[1] = 0;
|
||||
cuda_send_packet_to_host(s, obuf, 2);
|
||||
cuda_send_packet_to_host(s, obuf, 3);
|
||||
break;
|
||||
case CUDA_POWERDOWN:
|
||||
obuf[0] = CUDA_PACKET;
|
||||
obuf[1] = 0;
|
||||
cuda_send_packet_to_host(s, obuf, 2);
|
||||
cuda_send_packet_to_host(s, obuf, 3);
|
||||
qemu_system_shutdown_request();
|
||||
break;
|
||||
case CUDA_RESET_SYSTEM:
|
||||
obuf[0] = CUDA_PACKET;
|
||||
obuf[1] = 0;
|
||||
cuda_send_packet_to_host(s, obuf, 2);
|
||||
cuda_send_packet_to_host(s, obuf, 3);
|
||||
qemu_system_reset_request();
|
||||
break;
|
||||
case CUDA_COMBINED_FORMAT_IIC:
|
||||
obuf[0] = ERROR_PACKET;
|
||||
obuf[1] = 0x5;
|
||||
obuf[2] = CUDA_PACKET;
|
||||
obuf[3] = data[0];
|
||||
cuda_send_packet_to_host(s, obuf, 4);
|
||||
break;
|
||||
case CUDA_GET_SET_IIC:
|
||||
if (len == 4) {
|
||||
cuda_send_packet_to_host(s, obuf, 3);
|
||||
} else {
|
||||
obuf[0] = ERROR_PACKET;
|
||||
obuf[1] = 0x2;
|
||||
obuf[2] = CUDA_PACKET;
|
||||
obuf[3] = data[0];
|
||||
cuda_send_packet_to_host(s, obuf, 4);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -560,19 +624,21 @@ static void cuda_receive_packet_from_host(CUDAState *s,
|
||||
switch(data[0]) {
|
||||
case ADB_PACKET:
|
||||
{
|
||||
uint8_t obuf[ADB_MAX_OUT_LEN + 2];
|
||||
uint8_t obuf[ADB_MAX_OUT_LEN + 3];
|
||||
int olen;
|
||||
olen = adb_request(&s->adb_bus, obuf + 2, data + 1, len - 1);
|
||||
if (olen > 0) {
|
||||
obuf[0] = ADB_PACKET;
|
||||
obuf[1] = 0x00;
|
||||
cuda_send_packet_to_host(s, obuf, olen + 2);
|
||||
} else {
|
||||
/* error */
|
||||
obuf[0] = ADB_PACKET;
|
||||
obuf[1] = -olen;
|
||||
obuf[2] = data[1];
|
||||
olen = 0;
|
||||
cuda_send_packet_to_host(s, obuf, olen + 3);
|
||||
}
|
||||
cuda_send_packet_to_host(s, obuf, olen + 2);
|
||||
}
|
||||
break;
|
||||
case CUDA_PACKET:
|
||||
@ -671,7 +737,7 @@ static void cuda_reset(DeviceState *dev)
|
||||
|
||||
s->b = 0;
|
||||
s->a = 0;
|
||||
s->dirb = 0;
|
||||
s->dirb = 0xff;
|
||||
s->dira = 0;
|
||||
s->sr = 0;
|
||||
s->acr = 0;
|
||||
@ -688,8 +754,9 @@ static void cuda_reset(DeviceState *dev)
|
||||
s->timers[0].latch = 0xffff;
|
||||
set_counter(s, &s->timers[0], 0xffff);
|
||||
|
||||
s->timers[1].latch = 0;
|
||||
set_counter(s, &s->timers[1], 0xffff);
|
||||
s->timers[1].latch = 0xffff;
|
||||
|
||||
s->sr_delay_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_set_sr_int, s);
|
||||
}
|
||||
|
||||
static void cuda_realizefn(DeviceState *dev, Error **errp)
|
||||
@ -699,7 +766,8 @@ static void cuda_realizefn(DeviceState *dev, Error **errp)
|
||||
|
||||
s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer1, s);
|
||||
s->timers[0].frequency = s->frequency;
|
||||
s->timers[1].frequency = s->frequency;
|
||||
s->timers[1].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer2, s);
|
||||
s->timers[1].frequency = (SCALE_US * 6000) / 4700;
|
||||
|
||||
qemu_get_timedate(&tm, 0);
|
||||
s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
|
||||
|
@ -103,6 +103,9 @@ typedef struct CUDAState {
|
||||
uint8_t last_b;
|
||||
uint8_t last_acr;
|
||||
|
||||
/* MacOS 9 is racy and requires a delay upon setting the SR_INT bit */
|
||||
QEMUTimer *sr_delay_timer;
|
||||
|
||||
int data_in_size;
|
||||
int data_in_index;
|
||||
int data_out_index;
|
||||
|
@ -371,12 +371,13 @@ static void ppc_core99_init(MachineState *machine)
|
||||
/* 970 gets a U3 bus */
|
||||
pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
|
||||
machine_arch = ARCH_MAC99_U3;
|
||||
machine->usb |= defaults_enabled() && !machine->usb_disabled;
|
||||
} else {
|
||||
pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
|
||||
machine_arch = ARCH_MAC99;
|
||||
}
|
||||
|
||||
machine->usb |= defaults_enabled() && !machine->usb_disabled;
|
||||
|
||||
/* Timebase Frequency */
|
||||
if (kvm_enabled()) {
|
||||
tbfreq = kvmppc_get_tbfreq();
|
||||
|
@ -35,6 +35,7 @@ struct MonitorDef {
|
||||
};
|
||||
|
||||
const MonitorDef *target_monitor_defs(void);
|
||||
int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval);
|
||||
|
||||
CPUArchState *mon_get_cpu_env(void);
|
||||
CPUState *mon_get_cpu(void);
|
||||
|
10
monitor.c
10
monitor.c
@ -2136,6 +2136,8 @@ static int get_monitor_def(target_long *pval, const char *name)
|
||||
{
|
||||
const MonitorDef *md = target_monitor_defs();
|
||||
void *ptr;
|
||||
uint64_t tmp = 0;
|
||||
int ret;
|
||||
|
||||
if (md == NULL) {
|
||||
return -1;
|
||||
@ -2163,7 +2165,13 @@ static int get_monitor_def(target_long *pval, const char *name)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
ret = target_get_monitor_def(mon_get_cpu(), name, &tmp);
|
||||
if (!ret) {
|
||||
*pval = (target_long) tmp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void next(void)
|
||||
|
@ -36,4 +36,5 @@ stub-obj-y += cpus.o
|
||||
stub-obj-y += kvm.o
|
||||
stub-obj-y += qmp_pc_dimm_device_list.o
|
||||
stub-obj-y += target-monitor-defs.o
|
||||
stub-obj-y += target-get-monitor-def.o
|
||||
stub-obj-y += vhost.o
|
||||
|
31
stubs/target-get-monitor-def.c
Normal file
31
stubs/target-get-monitor-def.c
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Stub for target_get_monitor_def.
|
||||
*
|
||||
* Copyright IBM Corp., 2015
|
||||
*
|
||||
* Author: Alexey Kardashevskiy <aik@ozlabs.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
typedef struct CPUState CPUState;
|
||||
|
||||
int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval);
|
||||
|
||||
int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
|
||||
{
|
||||
return -1;
|
||||
}
|
@ -118,6 +118,8 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||
int flags);
|
||||
void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
|
||||
fprintf_function cpu_fprintf, int flags);
|
||||
int ppc_cpu_get_monitor_def(CPUState *cs, const char *name,
|
||||
uint64_t *pval);
|
||||
hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||
int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
int ppc_cpu_gdb_read_register_apple(CPUState *cpu, uint8_t *buf, int reg);
|
||||
|
@ -100,8 +100,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg,
|
||||
uint32_t ra, uint32_t rb)
|
||||
{
|
||||
if (likely(xer_bc != 0)) {
|
||||
if (unlikely((ra != 0 && reg < ra && (reg + xer_bc) > ra) ||
|
||||
(reg < rb && (reg + xer_bc) > rb))) {
|
||||
int num_used_regs = (xer_bc + 3) / 4;
|
||||
if (unlikely((ra != 0 && reg < ra && (reg + num_used_regs) > ra) ||
|
||||
(reg < rb && (reg + num_used_regs) > rb))) {
|
||||
helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
|
||||
POWERPC_EXCP_INVAL |
|
||||
POWERPC_EXCP_INVAL_LSWX);
|
||||
|
@ -39,18 +39,6 @@ static target_long monitor_get_ccr (const struct MonitorDef *md, int val)
|
||||
return u;
|
||||
}
|
||||
|
||||
static target_long monitor_get_msr (const struct MonitorDef *md, int val)
|
||||
{
|
||||
CPUArchState *env = mon_get_cpu_env();
|
||||
return env->msr;
|
||||
}
|
||||
|
||||
static target_long monitor_get_xer (const struct MonitorDef *md, int val)
|
||||
{
|
||||
CPUArchState *env = mon_get_cpu_env();
|
||||
return env->xer;
|
||||
}
|
||||
|
||||
static target_long monitor_get_decr (const struct MonitorDef *md, int val)
|
||||
{
|
||||
CPUArchState *env = mon_get_cpu_env();
|
||||
@ -76,176 +64,19 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
|
||||
dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1);
|
||||
}
|
||||
|
||||
|
||||
const MonitorDef monitor_defs[] = {
|
||||
/* General purpose registers */
|
||||
{ "r0", offsetof(CPUPPCState, gpr[0]) },
|
||||
{ "r1", offsetof(CPUPPCState, gpr[1]) },
|
||||
{ "r2", offsetof(CPUPPCState, gpr[2]) },
|
||||
{ "r3", offsetof(CPUPPCState, gpr[3]) },
|
||||
{ "r4", offsetof(CPUPPCState, gpr[4]) },
|
||||
{ "r5", offsetof(CPUPPCState, gpr[5]) },
|
||||
{ "r6", offsetof(CPUPPCState, gpr[6]) },
|
||||
{ "r7", offsetof(CPUPPCState, gpr[7]) },
|
||||
{ "r8", offsetof(CPUPPCState, gpr[8]) },
|
||||
{ "r9", offsetof(CPUPPCState, gpr[9]) },
|
||||
{ "r10", offsetof(CPUPPCState, gpr[10]) },
|
||||
{ "r11", offsetof(CPUPPCState, gpr[11]) },
|
||||
{ "r12", offsetof(CPUPPCState, gpr[12]) },
|
||||
{ "r13", offsetof(CPUPPCState, gpr[13]) },
|
||||
{ "r14", offsetof(CPUPPCState, gpr[14]) },
|
||||
{ "r15", offsetof(CPUPPCState, gpr[15]) },
|
||||
{ "r16", offsetof(CPUPPCState, gpr[16]) },
|
||||
{ "r17", offsetof(CPUPPCState, gpr[17]) },
|
||||
{ "r18", offsetof(CPUPPCState, gpr[18]) },
|
||||
{ "r19", offsetof(CPUPPCState, gpr[19]) },
|
||||
{ "r20", offsetof(CPUPPCState, gpr[20]) },
|
||||
{ "r21", offsetof(CPUPPCState, gpr[21]) },
|
||||
{ "r22", offsetof(CPUPPCState, gpr[22]) },
|
||||
{ "r23", offsetof(CPUPPCState, gpr[23]) },
|
||||
{ "r24", offsetof(CPUPPCState, gpr[24]) },
|
||||
{ "r25", offsetof(CPUPPCState, gpr[25]) },
|
||||
{ "r26", offsetof(CPUPPCState, gpr[26]) },
|
||||
{ "r27", offsetof(CPUPPCState, gpr[27]) },
|
||||
{ "r28", offsetof(CPUPPCState, gpr[28]) },
|
||||
{ "r29", offsetof(CPUPPCState, gpr[29]) },
|
||||
{ "r30", offsetof(CPUPPCState, gpr[30]) },
|
||||
{ "r31", offsetof(CPUPPCState, gpr[31]) },
|
||||
/* Floating point registers */
|
||||
{ "f0", offsetof(CPUPPCState, fpr[0]) },
|
||||
{ "f1", offsetof(CPUPPCState, fpr[1]) },
|
||||
{ "f2", offsetof(CPUPPCState, fpr[2]) },
|
||||
{ "f3", offsetof(CPUPPCState, fpr[3]) },
|
||||
{ "f4", offsetof(CPUPPCState, fpr[4]) },
|
||||
{ "f5", offsetof(CPUPPCState, fpr[5]) },
|
||||
{ "f6", offsetof(CPUPPCState, fpr[6]) },
|
||||
{ "f7", offsetof(CPUPPCState, fpr[7]) },
|
||||
{ "f8", offsetof(CPUPPCState, fpr[8]) },
|
||||
{ "f9", offsetof(CPUPPCState, fpr[9]) },
|
||||
{ "f10", offsetof(CPUPPCState, fpr[10]) },
|
||||
{ "f11", offsetof(CPUPPCState, fpr[11]) },
|
||||
{ "f12", offsetof(CPUPPCState, fpr[12]) },
|
||||
{ "f13", offsetof(CPUPPCState, fpr[13]) },
|
||||
{ "f14", offsetof(CPUPPCState, fpr[14]) },
|
||||
{ "f15", offsetof(CPUPPCState, fpr[15]) },
|
||||
{ "f16", offsetof(CPUPPCState, fpr[16]) },
|
||||
{ "f17", offsetof(CPUPPCState, fpr[17]) },
|
||||
{ "f18", offsetof(CPUPPCState, fpr[18]) },
|
||||
{ "f19", offsetof(CPUPPCState, fpr[19]) },
|
||||
{ "f20", offsetof(CPUPPCState, fpr[20]) },
|
||||
{ "f21", offsetof(CPUPPCState, fpr[21]) },
|
||||
{ "f22", offsetof(CPUPPCState, fpr[22]) },
|
||||
{ "f23", offsetof(CPUPPCState, fpr[23]) },
|
||||
{ "f24", offsetof(CPUPPCState, fpr[24]) },
|
||||
{ "f25", offsetof(CPUPPCState, fpr[25]) },
|
||||
{ "f26", offsetof(CPUPPCState, fpr[26]) },
|
||||
{ "f27", offsetof(CPUPPCState, fpr[27]) },
|
||||
{ "f28", offsetof(CPUPPCState, fpr[28]) },
|
||||
{ "f29", offsetof(CPUPPCState, fpr[29]) },
|
||||
{ "f30", offsetof(CPUPPCState, fpr[30]) },
|
||||
{ "f31", offsetof(CPUPPCState, fpr[31]) },
|
||||
{ "fpscr", offsetof(CPUPPCState, fpscr) },
|
||||
/* Next instruction pointer */
|
||||
{ "nip|pc", offsetof(CPUPPCState, nip) },
|
||||
{ "lr", offsetof(CPUPPCState, lr) },
|
||||
{ "ctr", offsetof(CPUPPCState, ctr) },
|
||||
{ "decr", 0, &monitor_get_decr, },
|
||||
{ "ccr", 0, &monitor_get_ccr, },
|
||||
{ "ccr|cr", 0, &monitor_get_ccr, },
|
||||
/* Machine state register */
|
||||
{ "msr", 0, &monitor_get_msr, },
|
||||
{ "xer", 0, &monitor_get_xer, },
|
||||
{ "xer", offsetof(CPUPPCState, xer) },
|
||||
{ "msr", offsetof(CPUPPCState, msr) },
|
||||
{ "tbu", 0, &monitor_get_tbu, },
|
||||
{ "tbl", 0, &monitor_get_tbl, },
|
||||
/* Segment registers */
|
||||
{ "sdr1", offsetof(CPUPPCState, spr[SPR_SDR1]) },
|
||||
{ "sr0", offsetof(CPUPPCState, sr[0]) },
|
||||
{ "sr1", offsetof(CPUPPCState, sr[1]) },
|
||||
{ "sr2", offsetof(CPUPPCState, sr[2]) },
|
||||
{ "sr3", offsetof(CPUPPCState, sr[3]) },
|
||||
{ "sr4", offsetof(CPUPPCState, sr[4]) },
|
||||
{ "sr5", offsetof(CPUPPCState, sr[5]) },
|
||||
{ "sr6", offsetof(CPUPPCState, sr[6]) },
|
||||
{ "sr7", offsetof(CPUPPCState, sr[7]) },
|
||||
{ "sr8", offsetof(CPUPPCState, sr[8]) },
|
||||
{ "sr9", offsetof(CPUPPCState, sr[9]) },
|
||||
{ "sr10", offsetof(CPUPPCState, sr[10]) },
|
||||
{ "sr11", offsetof(CPUPPCState, sr[11]) },
|
||||
{ "sr12", offsetof(CPUPPCState, sr[12]) },
|
||||
{ "sr13", offsetof(CPUPPCState, sr[13]) },
|
||||
{ "sr14", offsetof(CPUPPCState, sr[14]) },
|
||||
{ "sr15", offsetof(CPUPPCState, sr[15]) },
|
||||
/* Too lazy to put BATs... */
|
||||
{ "pvr", offsetof(CPUPPCState, spr[SPR_PVR]) },
|
||||
|
||||
{ "srr0", offsetof(CPUPPCState, spr[SPR_SRR0]) },
|
||||
{ "srr1", offsetof(CPUPPCState, spr[SPR_SRR1]) },
|
||||
{ "dar", offsetof(CPUPPCState, spr[SPR_DAR]) },
|
||||
{ "dsisr", offsetof(CPUPPCState, spr[SPR_DSISR]) },
|
||||
{ "cfar", offsetof(CPUPPCState, spr[SPR_CFAR]) },
|
||||
{ "sprg0", offsetof(CPUPPCState, spr[SPR_SPRG0]) },
|
||||
{ "sprg1", offsetof(CPUPPCState, spr[SPR_SPRG1]) },
|
||||
{ "sprg2", offsetof(CPUPPCState, spr[SPR_SPRG2]) },
|
||||
{ "sprg3", offsetof(CPUPPCState, spr[SPR_SPRG3]) },
|
||||
{ "sprg4", offsetof(CPUPPCState, spr[SPR_SPRG4]) },
|
||||
{ "sprg5", offsetof(CPUPPCState, spr[SPR_SPRG5]) },
|
||||
{ "sprg6", offsetof(CPUPPCState, spr[SPR_SPRG6]) },
|
||||
{ "sprg7", offsetof(CPUPPCState, spr[SPR_SPRG7]) },
|
||||
{ "pid", offsetof(CPUPPCState, spr[SPR_BOOKE_PID]) },
|
||||
{ "csrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR0]) },
|
||||
{ "csrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR1]) },
|
||||
{ "esr", offsetof(CPUPPCState, spr[SPR_BOOKE_ESR]) },
|
||||
{ "dear", offsetof(CPUPPCState, spr[SPR_BOOKE_DEAR]) },
|
||||
{ "mcsr", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSR]) },
|
||||
{ "tsr", offsetof(CPUPPCState, spr[SPR_BOOKE_TSR]) },
|
||||
{ "tcr", offsetof(CPUPPCState, spr[SPR_BOOKE_TCR]) },
|
||||
{ "vrsave", offsetof(CPUPPCState, spr[SPR_VRSAVE]) },
|
||||
{ "pir", offsetof(CPUPPCState, spr[SPR_BOOKE_PIR]) },
|
||||
{ "mcsrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR0]) },
|
||||
{ "mcsrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR1]) },
|
||||
{ "decar", offsetof(CPUPPCState, spr[SPR_BOOKE_DECAR]) },
|
||||
{ "ivpr", offsetof(CPUPPCState, spr[SPR_BOOKE_IVPR]) },
|
||||
{ "epcr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPCR]) },
|
||||
{ "sprg8", offsetof(CPUPPCState, spr[SPR_BOOKE_SPRG8]) },
|
||||
{ "ivor0", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR0]) },
|
||||
{ "ivor1", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR1]) },
|
||||
{ "ivor2", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR2]) },
|
||||
{ "ivor3", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR3]) },
|
||||
{ "ivor4", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR4]) },
|
||||
{ "ivor5", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR5]) },
|
||||
{ "ivor6", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR6]) },
|
||||
{ "ivor7", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR7]) },
|
||||
{ "ivor8", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR8]) },
|
||||
{ "ivor9", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR9]) },
|
||||
{ "ivor10", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR10]) },
|
||||
{ "ivor11", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR11]) },
|
||||
{ "ivor12", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR12]) },
|
||||
{ "ivor13", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR13]) },
|
||||
{ "ivor14", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR14]) },
|
||||
{ "ivor15", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR15]) },
|
||||
{ "ivor32", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR32]) },
|
||||
{ "ivor33", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR33]) },
|
||||
{ "ivor34", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR34]) },
|
||||
{ "ivor35", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR35]) },
|
||||
{ "ivor36", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR36]) },
|
||||
{ "ivor37", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR37]) },
|
||||
{ "mas0", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS0]) },
|
||||
{ "mas1", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS1]) },
|
||||
{ "mas2", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS2]) },
|
||||
{ "mas3", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS3]) },
|
||||
{ "mas4", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS4]) },
|
||||
{ "mas6", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS6]) },
|
||||
{ "mas7", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS7]) },
|
||||
{ "mmucfg", offsetof(CPUPPCState, spr[SPR_MMUCFG]) },
|
||||
{ "tlb0cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB0CFG]) },
|
||||
{ "tlb1cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB1CFG]) },
|
||||
{ "epr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPR]) },
|
||||
{ "eplc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPLC]) },
|
||||
{ "epsc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPSC]) },
|
||||
{ "svr", offsetof(CPUPPCState, spr[SPR_E500_SVR]) },
|
||||
{ "mcar", offsetof(CPUPPCState, spr[SPR_Exxx_MCAR]) },
|
||||
{ "pid1", offsetof(CPUPPCState, spr[SPR_BOOKE_PID1]) },
|
||||
{ "pid2", offsetof(CPUPPCState, spr[SPR_BOOKE_PID2]) },
|
||||
{ "hid0", offsetof(CPUPPCState, spr[SPR_HID0]) },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
@ -253,3 +84,63 @@ const MonitorDef *target_monitor_defs(void)
|
||||
{
|
||||
return monitor_defs;
|
||||
}
|
||||
|
||||
static int ppc_cpu_get_reg_num(const char *numstr, int maxnum, int *pregnum)
|
||||
{
|
||||
int regnum;
|
||||
char *endptr = NULL;
|
||||
|
||||
if (!*numstr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
regnum = strtoul(numstr, &endptr, 10);
|
||||
if (*endptr || (regnum >= maxnum)) {
|
||||
return false;
|
||||
}
|
||||
*pregnum = regnum;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
|
||||
{
|
||||
int i, regnum;
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
|
||||
/* General purpose registers */
|
||||
if ((tolower(name[0]) == 'r') &&
|
||||
ppc_cpu_get_reg_num(name + 1, ARRAY_SIZE(env->gpr), ®num)) {
|
||||
*pval = env->gpr[regnum];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Floating point registers */
|
||||
if ((tolower(name[0]) == 'f') &&
|
||||
ppc_cpu_get_reg_num(name + 1, ARRAY_SIZE(env->fpr), ®num)) {
|
||||
*pval = env->fpr[regnum];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Special purpose registers */
|
||||
for (i = 0; i < ARRAY_SIZE(env->spr_cb); ++i) {
|
||||
ppc_spr_t *spr = &env->spr_cb[i];
|
||||
|
||||
if (spr->name && (strcasecmp(name, spr->name) == 0)) {
|
||||
*pval = env->spr[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Segment registers */
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if ((strncasecmp(name, "sr", 2) == 0) &&
|
||||
ppc_cpu_get_reg_num(name + 2, ARRAY_SIZE(env->sr), ®num)) {
|
||||
*pval = env->sr[regnum];
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -9884,7 +9884,7 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
|
||||
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
|
||||
#endif
|
||||
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
|
||||
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
|
||||
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
|
||||
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
|
||||
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
|
||||
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
|
||||
|
Loading…
Reference in New Issue
Block a user