mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf
* 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf: PPC: e500: Select MPIC v4.2 on ppce500 platform PPC: e500: fix mpic_iack address openpic: add basic support for MPIC v4.2 openpic: fix timer address decoding openpic: fix remaining issues from idr-to-destmask conversion pseries: Adjust default VIO address allocations to play better with libvirt pseries: Improve handling of multiple PCI host bridges target-ppc: Give a meaningful error if too many threads are specified cuda: Move ADB bus into CUDA state adb: QOM'ify ADB devices adb: QOM'ify Apple Desktop Bus cuda: QOM'ify CUDA ide/macio: QOM'ify MacIO IDE mac_nvram: QOM'ify MacIO NVRAM mac_nvram: Mark as Big Endian mac_nvram: Clean up public API macio: Split MacIO in two macio: Delay qdev init until all fields are initialized macio: QOM'ify some more ppc: Move Mac machines to hw/ppc/
This commit is contained in:
+2
-2
@@ -380,7 +380,7 @@ New World
|
||||
M: Alexander Graf <agraf@suse.de>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/ppc_newworld.c
|
||||
F: hw/ppc/mac_newworld.c
|
||||
F: hw/unin_pci.c
|
||||
F: hw/dec_pci.[hc]
|
||||
|
||||
@@ -388,7 +388,7 @@ Old World
|
||||
M: Alexander Graf <agraf@suse.de>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/ppc_oldworld.c
|
||||
F: hw/ppc/mac_oldworld.c
|
||||
F: hw/grackle_pci.c
|
||||
|
||||
PReP
|
||||
|
||||
@@ -48,16 +48,21 @@ do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
|
||||
#define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
|
||||
|
||||
/* ADB default device IDs (upper 4 bits of ADB command byte) */
|
||||
#define ADB_DONGLE 1
|
||||
#define ADB_KEYBOARD 2
|
||||
#define ADB_MOUSE 3
|
||||
#define ADB_TABLET 4
|
||||
#define ADB_MODEM 5
|
||||
#define ADB_MISC 7
|
||||
#define ADB_DEVID_DONGLE 1
|
||||
#define ADB_DEVID_KEYBOARD 2
|
||||
#define ADB_DEVID_MOUSE 3
|
||||
#define ADB_DEVID_TABLET 4
|
||||
#define ADB_DEVID_MODEM 5
|
||||
#define ADB_DEVID_MISC 7
|
||||
|
||||
/* error codes */
|
||||
#define ADB_RET_NOTPRESENT (-2)
|
||||
|
||||
static void adb_device_reset(ADBDevice *d)
|
||||
{
|
||||
qdev_reset_all(DEVICE(d));
|
||||
}
|
||||
|
||||
int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
|
||||
{
|
||||
ADBDevice *d;
|
||||
@@ -66,18 +71,17 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
|
||||
cmd = buf[0] & 0xf;
|
||||
if (cmd == ADB_BUSRESET) {
|
||||
for(i = 0; i < s->nb_devices; i++) {
|
||||
d = &s->devices[i];
|
||||
if (d->devreset) {
|
||||
d->devreset(d);
|
||||
}
|
||||
d = s->devices[i];
|
||||
adb_device_reset(d);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
devaddr = buf[0] >> 4;
|
||||
for(i = 0; i < s->nb_devices; i++) {
|
||||
d = &s->devices[i];
|
||||
d = s->devices[i];
|
||||
if (d->devaddr == devaddr) {
|
||||
return d->devreq(d, obuf, buf, len);
|
||||
ADBDeviceClass *adc = ADB_DEVICE_GET_CLASS(d);
|
||||
return adc->devreq(d, obuf, buf, len);
|
||||
}
|
||||
}
|
||||
return ADB_RET_NOTPRESENT;
|
||||
@@ -94,7 +98,7 @@ int adb_poll(ADBBusState *s, uint8_t *obuf)
|
||||
for(i = 0; i < s->nb_devices; i++) {
|
||||
if (s->poll_index >= s->nb_devices)
|
||||
s->poll_index = 0;
|
||||
d = &s->devices[s->poll_index];
|
||||
d = s->devices[s->poll_index];
|
||||
buf[0] = ADB_READREG | (d->devaddr << 4);
|
||||
olen = adb_request(s, obuf + 1, buf, 1);
|
||||
/* if there is data, we poll again the same device */
|
||||
@@ -108,32 +112,67 @@ int adb_poll(ADBBusState *s, uint8_t *obuf)
|
||||
return olen;
|
||||
}
|
||||
|
||||
static ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
|
||||
ADBDeviceRequest *devreq,
|
||||
ADBDeviceReset *devreset,
|
||||
void *opaque)
|
||||
static const TypeInfo adb_bus_type_info = {
|
||||
.name = TYPE_ADB_BUS,
|
||||
.parent = TYPE_BUS,
|
||||
.instance_size = sizeof(ADBBusState),
|
||||
};
|
||||
|
||||
static void adb_device_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
ADBDevice *d;
|
||||
if (s->nb_devices >= MAX_ADB_DEVICES)
|
||||
return NULL;
|
||||
d = &s->devices[s->nb_devices++];
|
||||
d->bus = s;
|
||||
d->devaddr = devaddr;
|
||||
d->devreq = devreq;
|
||||
d->devreset = devreset;
|
||||
d->opaque = opaque;
|
||||
qemu_register_reset((QEMUResetHandler *)devreset, d);
|
||||
return d;
|
||||
ADBDevice *d = ADB_DEVICE(dev);
|
||||
ADBBusState *bus = ADB_BUS(qdev_get_parent_bus(dev));
|
||||
|
||||
if (bus->nb_devices >= MAX_ADB_DEVICES) {
|
||||
return;
|
||||
}
|
||||
|
||||
bus->devices[bus->nb_devices++] = d;
|
||||
}
|
||||
|
||||
static void adb_device_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
dc->realize = adb_device_realizefn;
|
||||
dc->bus_type = TYPE_ADB_BUS;
|
||||
}
|
||||
|
||||
static const TypeInfo adb_device_type_info = {
|
||||
.name = TYPE_ADB_DEVICE,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(ADBDevice),
|
||||
.abstract = true,
|
||||
.class_init = adb_device_class_init,
|
||||
};
|
||||
|
||||
/***************************************************************/
|
||||
/* Keyboard ADB device */
|
||||
|
||||
#define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
|
||||
|
||||
typedef struct KBDState {
|
||||
/*< private >*/
|
||||
ADBDevice parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
uint8_t data[128];
|
||||
int rptr, wptr, count;
|
||||
} KBDState;
|
||||
|
||||
#define ADB_KEYBOARD_CLASS(class) \
|
||||
OBJECT_CLASS_CHECK(ADBKeyboardClass, (class), TYPE_ADB_KEYBOARD)
|
||||
#define ADB_KEYBOARD_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(ADBKeyboardClass, (obj), TYPE_ADB_KEYBOARD)
|
||||
|
||||
typedef struct ADBKeyboardClass {
|
||||
/*< private >*/
|
||||
ADBDeviceClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
} ADBKeyboardClass;
|
||||
|
||||
static const uint8_t pc_to_adb_keycode[256] = {
|
||||
0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
|
||||
12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1,
|
||||
@@ -155,8 +194,7 @@ static const uint8_t pc_to_adb_keycode[256] = {
|
||||
|
||||
static void adb_kbd_put_keycode(void *opaque, int keycode)
|
||||
{
|
||||
ADBDevice *d = opaque;
|
||||
KBDState *s = d->opaque;
|
||||
KBDState *s = opaque;
|
||||
|
||||
if (s->count < sizeof(s->data)) {
|
||||
s->data[s->wptr] = keycode;
|
||||
@@ -169,7 +207,7 @@ static void adb_kbd_put_keycode(void *opaque, int keycode)
|
||||
static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
|
||||
{
|
||||
static int ext_keycode;
|
||||
KBDState *s = d->opaque;
|
||||
KBDState *s = ADB_KEYBOARD(d);
|
||||
int adb_keycode, keycode;
|
||||
int olen;
|
||||
|
||||
@@ -203,7 +241,7 @@ static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
|
||||
static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
|
||||
const uint8_t *buf, int len)
|
||||
{
|
||||
KBDState *s = d->opaque;
|
||||
KBDState *s = ADB_KEYBOARD(d);
|
||||
int cmd, reg, olen;
|
||||
|
||||
if ((buf[0] & 0x0f) == ADB_FLUSH) {
|
||||
@@ -275,41 +313,90 @@ static const VMStateDescription vmstate_adb_kbd = {
|
||||
}
|
||||
};
|
||||
|
||||
static int adb_kbd_reset(ADBDevice *d)
|
||||
static void adb_kbd_reset(DeviceState *dev)
|
||||
{
|
||||
KBDState *s = d->opaque;
|
||||
ADBDevice *d = ADB_DEVICE(dev);
|
||||
KBDState *s = ADB_KEYBOARD(dev);
|
||||
|
||||
d->handler = 1;
|
||||
d->devaddr = ADB_KEYBOARD;
|
||||
memset(s, 0, sizeof(KBDState));
|
||||
|
||||
return 0;
|
||||
d->devaddr = ADB_DEVID_KEYBOARD;
|
||||
memset(s->data, 0, sizeof(s->data));
|
||||
s->rptr = 0;
|
||||
s->wptr = 0;
|
||||
s->count = 0;
|
||||
}
|
||||
|
||||
void adb_kbd_init(ADBBusState *bus)
|
||||
static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
ADBDevice *d;
|
||||
KBDState *s;
|
||||
s = g_malloc0(sizeof(KBDState));
|
||||
d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
|
||||
adb_kbd_reset, s);
|
||||
ADBDevice *d = ADB_DEVICE(dev);
|
||||
ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
|
||||
|
||||
akc->parent_realize(dev, errp);
|
||||
|
||||
qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
|
||||
vmstate_register(NULL, -1, &vmstate_adb_kbd, s);
|
||||
}
|
||||
|
||||
static void adb_kbd_initfn(Object *obj)
|
||||
{
|
||||
ADBDevice *d = ADB_DEVICE(obj);
|
||||
|
||||
d->devaddr = ADB_DEVID_KEYBOARD;
|
||||
}
|
||||
|
||||
static void adb_kbd_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
|
||||
ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
|
||||
|
||||
akc->parent_realize = dc->realize;
|
||||
dc->realize = adb_kbd_realizefn;
|
||||
|
||||
adc->devreq = adb_kbd_request;
|
||||
dc->reset = adb_kbd_reset;
|
||||
dc->vmsd = &vmstate_adb_kbd;
|
||||
}
|
||||
|
||||
static const TypeInfo adb_kbd_type_info = {
|
||||
.name = TYPE_ADB_KEYBOARD,
|
||||
.parent = TYPE_ADB_DEVICE,
|
||||
.instance_size = sizeof(KBDState),
|
||||
.instance_init = adb_kbd_initfn,
|
||||
.class_init = adb_kbd_class_init,
|
||||
.class_size = sizeof(ADBKeyboardClass),
|
||||
};
|
||||
|
||||
/***************************************************************/
|
||||
/* Mouse ADB device */
|
||||
|
||||
#define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
|
||||
|
||||
typedef struct MouseState {
|
||||
/*< public >*/
|
||||
ADBDevice parent_obj;
|
||||
/*< private >*/
|
||||
|
||||
int buttons_state, last_buttons_state;
|
||||
int dx, dy, dz;
|
||||
} MouseState;
|
||||
|
||||
#define ADB_MOUSE_CLASS(class) \
|
||||
OBJECT_CLASS_CHECK(ADBMouseClass, (class), TYPE_ADB_MOUSE)
|
||||
#define ADB_MOUSE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(ADBMouseClass, (obj), TYPE_ADB_MOUSE)
|
||||
|
||||
typedef struct ADBMouseClass {
|
||||
/*< public >*/
|
||||
ADBDeviceClass parent_class;
|
||||
/*< private >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
} ADBMouseClass;
|
||||
|
||||
static void adb_mouse_event(void *opaque,
|
||||
int dx1, int dy1, int dz1, int buttons_state)
|
||||
{
|
||||
ADBDevice *d = opaque;
|
||||
MouseState *s = d->opaque;
|
||||
MouseState *s = opaque;
|
||||
|
||||
s->dx += dx1;
|
||||
s->dy += dy1;
|
||||
@@ -320,7 +407,7 @@ static void adb_mouse_event(void *opaque,
|
||||
|
||||
static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
|
||||
{
|
||||
MouseState *s = d->opaque;
|
||||
MouseState *s = ADB_MOUSE(d);
|
||||
int dx, dy;
|
||||
|
||||
if (s->last_buttons_state == s->buttons_state &&
|
||||
@@ -359,7 +446,7 @@ static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
|
||||
static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
|
||||
const uint8_t *buf, int len)
|
||||
{
|
||||
MouseState *s = d->opaque;
|
||||
MouseState *s = ADB_MOUSE(d);
|
||||
int cmd, reg, olen;
|
||||
|
||||
if ((buf[0] & 0x0f) == ADB_FLUSH) {
|
||||
@@ -416,15 +503,15 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
|
||||
return olen;
|
||||
}
|
||||
|
||||
static int adb_mouse_reset(ADBDevice *d)
|
||||
static void adb_mouse_reset(DeviceState *dev)
|
||||
{
|
||||
MouseState *s = d->opaque;
|
||||
ADBDevice *d = ADB_DEVICE(dev);
|
||||
MouseState *s = ADB_MOUSE(dev);
|
||||
|
||||
d->handler = 2;
|
||||
d->devaddr = ADB_MOUSE;
|
||||
memset(s, 0, sizeof(MouseState));
|
||||
|
||||
return 0;
|
||||
d->devaddr = ADB_DEVID_MOUSE;
|
||||
s->last_buttons_state = s->buttons_state = 0;
|
||||
s->dx = s->dy = s->dz = 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_adb_mouse = {
|
||||
@@ -442,14 +529,53 @@ static const VMStateDescription vmstate_adb_mouse = {
|
||||
}
|
||||
};
|
||||
|
||||
void adb_mouse_init(ADBBusState *bus)
|
||||
static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
ADBDevice *d;
|
||||
MouseState *s;
|
||||
MouseState *s = ADB_MOUSE(dev);
|
||||
ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
|
||||
|
||||
s = g_malloc0(sizeof(MouseState));
|
||||
d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
|
||||
adb_mouse_reset, s);
|
||||
qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
|
||||
vmstate_register(NULL, -1, &vmstate_adb_mouse, s);
|
||||
amc->parent_realize(dev, errp);
|
||||
|
||||
qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
|
||||
}
|
||||
|
||||
static void adb_mouse_initfn(Object *obj)
|
||||
{
|
||||
ADBDevice *d = ADB_DEVICE(obj);
|
||||
|
||||
d->devaddr = ADB_DEVID_MOUSE;
|
||||
}
|
||||
|
||||
static void adb_mouse_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
|
||||
ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
|
||||
|
||||
amc->parent_realize = dc->realize;
|
||||
dc->realize = adb_mouse_realizefn;
|
||||
|
||||
adc->devreq = adb_mouse_request;
|
||||
dc->reset = adb_mouse_reset;
|
||||
dc->vmsd = &vmstate_adb_mouse;
|
||||
}
|
||||
|
||||
static const TypeInfo adb_mouse_type_info = {
|
||||
.name = TYPE_ADB_MOUSE,
|
||||
.parent = TYPE_ADB_DEVICE,
|
||||
.instance_size = sizeof(MouseState),
|
||||
.instance_init = adb_mouse_initfn,
|
||||
.class_init = adb_mouse_class_init,
|
||||
.class_size = sizeof(ADBMouseClass),
|
||||
};
|
||||
|
||||
|
||||
static void adb_register_types(void)
|
||||
{
|
||||
type_register_static(&adb_bus_type_info);
|
||||
type_register_static(&adb_device_type_info);
|
||||
type_register_static(&adb_kbd_type_info);
|
||||
type_register_static(&adb_mouse_type_info);
|
||||
}
|
||||
|
||||
type_init(adb_register_types)
|
||||
|
||||
@@ -26,38 +26,62 @@
|
||||
#if !defined(__ADB_H__)
|
||||
#define __ADB_H__
|
||||
|
||||
#include "qdev.h"
|
||||
|
||||
#define MAX_ADB_DEVICES 16
|
||||
|
||||
#define ADB_MAX_OUT_LEN 16
|
||||
|
||||
typedef struct ADBBusState ADBBusState;
|
||||
typedef struct ADBDevice ADBDevice;
|
||||
|
||||
/* buf = NULL means polling */
|
||||
typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
|
||||
const uint8_t *buf, int len);
|
||||
typedef int ADBDeviceReset(ADBDevice *d);
|
||||
|
||||
#define TYPE_ADB_DEVICE "adb-device"
|
||||
#define ADB_DEVICE(obj) OBJECT_CHECK(ADBDevice, (obj), TYPE_ADB_DEVICE)
|
||||
|
||||
struct ADBDevice {
|
||||
struct ADBBusState *bus;
|
||||
/*< private >*/
|
||||
DeviceState parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
int devaddr;
|
||||
int handler;
|
||||
ADBDeviceRequest *devreq;
|
||||
ADBDeviceReset *devreset;
|
||||
void *opaque;
|
||||
};
|
||||
|
||||
typedef struct ADBBusState {
|
||||
ADBDevice devices[MAX_ADB_DEVICES];
|
||||
#define ADB_DEVICE_CLASS(cls) \
|
||||
OBJECT_CLASS_CHECK(ADBDeviceClass, (cls), TYPE_ADB_DEVICE)
|
||||
#define ADB_DEVICE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(ADBDeviceClass, (obj), TYPE_ADB_DEVICE)
|
||||
|
||||
typedef struct ADBDeviceClass {
|
||||
/*< private >*/
|
||||
DeviceClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
ADBDeviceRequest *devreq;
|
||||
} ADBDeviceClass;
|
||||
|
||||
#define TYPE_ADB_BUS "apple-desktop-bus"
|
||||
#define ADB_BUS(obj) OBJECT_CHECK(ADBBusState, (obj), TYPE_ADB_BUS)
|
||||
|
||||
struct ADBBusState {
|
||||
/*< private >*/
|
||||
BusState parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
ADBDevice *devices[MAX_ADB_DEVICES];
|
||||
int nb_devices;
|
||||
int poll_index;
|
||||
} ADBBusState;
|
||||
};
|
||||
|
||||
int adb_request(ADBBusState *s, uint8_t *buf_out,
|
||||
const uint8_t *buf, int len);
|
||||
int adb_poll(ADBBusState *s, uint8_t *buf_out);
|
||||
|
||||
void adb_kbd_init(ADBBusState *bus);
|
||||
void adb_mouse_init(ADBBusState *bus);
|
||||
#define TYPE_ADB_KEYBOARD "adb-keyboard"
|
||||
#define TYPE_ADB_MOUSE "adb-mouse"
|
||||
|
||||
extern ADBBusState adb_bus;
|
||||
#endif /* !defined(__ADB_H__) */
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "hw.h"
|
||||
#include "ppc_mac.h"
|
||||
#include "ppc/mac.h"
|
||||
#include "adb.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
@@ -108,50 +108,6 @@
|
||||
/* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
|
||||
#define RTC_OFFSET 2082844800
|
||||
|
||||
typedef struct CUDATimer {
|
||||
int index;
|
||||
uint16_t latch;
|
||||
uint16_t counter_value; /* counter value at load time */
|
||||
int64_t load_time;
|
||||
int64_t next_irq_time;
|
||||
QEMUTimer *timer;
|
||||
} CUDATimer;
|
||||
|
||||
typedef struct CUDAState {
|
||||
MemoryRegion mem;
|
||||
/* cuda registers */
|
||||
uint8_t b; /* B-side data */
|
||||
uint8_t a; /* A-side data */
|
||||
uint8_t dirb; /* B-side direction (1=output) */
|
||||
uint8_t dira; /* A-side direction (1=output) */
|
||||
uint8_t sr; /* Shift register */
|
||||
uint8_t acr; /* Auxiliary control register */
|
||||
uint8_t pcr; /* Peripheral control register */
|
||||
uint8_t ifr; /* Interrupt flag register */
|
||||
uint8_t ier; /* Interrupt enable register */
|
||||
uint8_t anh; /* A-side data, no handshake */
|
||||
|
||||
CUDATimer timers[2];
|
||||
|
||||
uint32_t tick_offset;
|
||||
|
||||
uint8_t last_b; /* last value of B register */
|
||||
uint8_t last_acr; /* last value of B register */
|
||||
|
||||
int data_in_size;
|
||||
int data_in_index;
|
||||
int data_out_index;
|
||||
|
||||
qemu_irq irq;
|
||||
uint8_t autopoll;
|
||||
uint8_t data_in[128];
|
||||
uint8_t data_out[16];
|
||||
QEMUTimer *adb_poll_timer;
|
||||
} CUDAState;
|
||||
|
||||
static CUDAState cuda_state;
|
||||
ADBBusState adb_bus;
|
||||
|
||||
static void cuda_update(CUDAState *s);
|
||||
static void cuda_receive_packet_from_host(CUDAState *s,
|
||||
const uint8_t *data, int len);
|
||||
@@ -501,7 +457,7 @@ static void cuda_adb_poll(void *opaque)
|
||||
uint8_t obuf[ADB_MAX_OUT_LEN + 2];
|
||||
int olen;
|
||||
|
||||
olen = adb_poll(&adb_bus, obuf + 2);
|
||||
olen = adb_poll(&s->adb_bus, obuf + 2);
|
||||
if (olen > 0) {
|
||||
obuf[0] = ADB_PACKET;
|
||||
obuf[1] = 0x40; /* polled data */
|
||||
@@ -597,7 +553,7 @@ static void cuda_receive_packet_from_host(CUDAState *s,
|
||||
{
|
||||
uint8_t obuf[ADB_MAX_OUT_LEN + 2];
|
||||
int olen;
|
||||
olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1);
|
||||
olen = adb_request(&s->adb_bus, obuf + 2, data + 1, len - 1);
|
||||
if (olen > 0) {
|
||||
obuf[0] = ADB_PACKET;
|
||||
obuf[1] = 0x00;
|
||||
@@ -701,9 +657,9 @@ static const VMStateDescription vmstate_cuda = {
|
||||
}
|
||||
};
|
||||
|
||||
static void cuda_reset(void *opaque)
|
||||
static void cuda_reset(DeviceState *dev)
|
||||
{
|
||||
CUDAState *s = opaque;
|
||||
CUDAState *s = CUDA(dev);
|
||||
|
||||
s->b = 0;
|
||||
s->a = 0;
|
||||
@@ -728,25 +684,57 @@ static void cuda_reset(void *opaque)
|
||||
set_counter(s, &s->timers[1], 0xffff);
|
||||
}
|
||||
|
||||
void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq)
|
||||
static void cuda_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
CUDAState *s = CUDA(dev);
|
||||
struct tm tm;
|
||||
CUDAState *s = &cuda_state;
|
||||
|
||||
s->irq = irq;
|
||||
|
||||
s->timers[0].index = 0;
|
||||
s->timers[0].timer = qemu_new_timer_ns(vm_clock, cuda_timer1, s);
|
||||
|
||||
s->timers[1].index = 1;
|
||||
|
||||
qemu_get_timedate(&tm, 0);
|
||||
s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
|
||||
|
||||
s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
|
||||
memory_region_init_io(&s->mem, &cuda_ops, s, "cuda", 0x2000);
|
||||
|
||||
*cuda_mem = &s->mem;
|
||||
vmstate_register(NULL, -1, &vmstate_cuda, s);
|
||||
qemu_register_reset(cuda_reset, s);
|
||||
}
|
||||
|
||||
static void cuda_initfn(Object *obj)
|
||||
{
|
||||
SysBusDevice *d = SYS_BUS_DEVICE(obj);
|
||||
CUDAState *s = CUDA(obj);
|
||||
int i;
|
||||
|
||||
memory_region_init_io(&s->mem, &cuda_ops, s, "cuda", 0x2000);
|
||||
sysbus_init_mmio(d, &s->mem);
|
||||
sysbus_init_irq(d, &s->irq);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(s->timers); i++) {
|
||||
s->timers[i].index = i;
|
||||
}
|
||||
|
||||
qbus_create_inplace((BusState *)&s->adb_bus, TYPE_ADB_BUS, DEVICE(obj),
|
||||
"adb.0");
|
||||
}
|
||||
|
||||
static void cuda_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
dc->realize = cuda_realizefn;
|
||||
dc->reset = cuda_reset;
|
||||
dc->vmsd = &vmstate_cuda;
|
||||
}
|
||||
|
||||
static const TypeInfo cuda_type_info = {
|
||||
.name = TYPE_CUDA,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(CUDAState),
|
||||
.instance_init = cuda_initfn,
|
||||
.class_init = cuda_class_init,
|
||||
};
|
||||
|
||||
static void cuda_register_types(void)
|
||||
{
|
||||
type_register_static(&cuda_type_info);
|
||||
}
|
||||
|
||||
type_init(cuda_register_types)
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "pci/pci_host.h"
|
||||
#include "ppc_mac.h"
|
||||
#include "ppc/mac.h"
|
||||
#include "pci/pci.h"
|
||||
|
||||
/* debug Grackle */
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "hw.h"
|
||||
#include "ppc_mac.h"
|
||||
#include "ppc/mac.h"
|
||||
|
||||
/* debug PIC */
|
||||
//#define DEBUG_PIC
|
||||
|
||||
@@ -19,10 +19,6 @@ PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
|
||||
PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
|
||||
void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
|
||||
|
||||
/* ide-macio.c */
|
||||
MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
|
||||
void *dbdma, int channel, qemu_irq dma_irq);
|
||||
|
||||
/* ide-mmio.c */
|
||||
void mmio_ide_init (hwaddr membase, hwaddr membase2,
|
||||
MemoryRegion *address_space,
|
||||
|
||||
+62
-28
@@ -22,9 +22,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include <hw/hw.h>
|
||||
#include <hw/ppc_mac.h>
|
||||
#include <hw/mac_dbdma.h>
|
||||
#include "hw/hw.h"
|
||||
#include "hw/ppc/mac.h"
|
||||
#include "hw/mac_dbdma.h"
|
||||
#include "block/block.h"
|
||||
#include "sysemu/dma.h"
|
||||
|
||||
@@ -33,12 +33,6 @@
|
||||
/***********************************************************/
|
||||
/* MacIO based PowerPC IDE */
|
||||
|
||||
typedef struct MACIOIDEState {
|
||||
MemoryRegion mem;
|
||||
IDEBus bus;
|
||||
BlockDriverAIOCB *aiocb;
|
||||
} MACIOIDEState;
|
||||
|
||||
#define MACIO_PAGE_SIZE 4096
|
||||
|
||||
static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
|
||||
@@ -321,30 +315,70 @@ static const VMStateDescription vmstate_pmac = {
|
||||
}
|
||||
};
|
||||
|
||||
static void pmac_ide_reset(void *opaque)
|
||||
static void macio_ide_reset(DeviceState *dev)
|
||||
{
|
||||
MACIOIDEState *d = opaque;
|
||||
MACIOIDEState *d = MACIO_IDE(dev);
|
||||
|
||||
ide_bus_reset(&d->bus);
|
||||
}
|
||||
|
||||
/* hd_table must contain 4 block drivers */
|
||||
/* PowerMac uses memory mapped registers, not I/O. Return the memory
|
||||
I/O index to access the ide. */
|
||||
MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
|
||||
void *dbdma, int channel, qemu_irq dma_irq)
|
||||
static void macio_ide_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
MACIOIDEState *d;
|
||||
MACIOIDEState *s = MACIO_IDE(dev);
|
||||
|
||||
d = g_malloc0(sizeof(MACIOIDEState));
|
||||
ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq);
|
||||
|
||||
if (dbdma)
|
||||
DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d);
|
||||
|
||||
memory_region_init_io(&d->mem, &pmac_ide_ops, d, "pmac-ide", 0x1000);
|
||||
vmstate_register(NULL, 0, &vmstate_pmac, d);
|
||||
qemu_register_reset(pmac_ide_reset, d);
|
||||
|
||||
return &d->mem;
|
||||
ide_init2(&s->bus, s->irq);
|
||||
}
|
||||
|
||||
static void macio_ide_initfn(Object *obj)
|
||||
{
|
||||
SysBusDevice *d = SYS_BUS_DEVICE(obj);
|
||||
MACIOIDEState *s = MACIO_IDE(obj);
|
||||
|
||||
ide_bus_new(&s->bus, DEVICE(obj), 0);
|
||||
memory_region_init_io(&s->mem, &pmac_ide_ops, s, "pmac-ide", 0x1000);
|
||||
sysbus_init_mmio(d, &s->mem);
|
||||
sysbus_init_irq(d, &s->irq);
|
||||
sysbus_init_irq(d, &s->dma_irq);
|
||||
}
|
||||
|
||||
static void macio_ide_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
dc->realize = macio_ide_realizefn;
|
||||
dc->reset = macio_ide_reset;
|
||||
dc->vmsd = &vmstate_pmac;
|
||||
}
|
||||
|
||||
static const TypeInfo macio_ide_type_info = {
|
||||
.name = TYPE_MACIO_IDE,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(MACIOIDEState),
|
||||
.instance_init = macio_ide_initfn,
|
||||
.class_init = macio_ide_class_init,
|
||||
};
|
||||
|
||||
static void macio_ide_register_types(void)
|
||||
{
|
||||
type_register_static(&macio_ide_type_info);
|
||||
}
|
||||
|
||||
/* hd_table must contain 4 block drivers */
|
||||
void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (hd_table[i]) {
|
||||
ide_create_drive(&s->bus, i, hd_table[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel)
|
||||
{
|
||||
DBDMA_register_channel(dbdma, channel, s->dma_irq,
|
||||
pmac_ide_transfer, pmac_ide_flush, s);
|
||||
}
|
||||
|
||||
type_init(macio_ide_register_types)
|
||||
|
||||
+54
-36
@@ -25,7 +25,7 @@
|
||||
#include "hw.h"
|
||||
#include "firmware_abi.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "ppc_mac.h"
|
||||
#include "ppc/mac.h"
|
||||
|
||||
/* debug NVR */
|
||||
//#define DEBUG_NVR
|
||||
@@ -37,37 +37,29 @@
|
||||
#define NVR_DPRINTF(fmt, ...)
|
||||
#endif
|
||||
|
||||
struct MacIONVRAMState {
|
||||
uint32_t size;
|
||||
MemoryRegion mem;
|
||||
unsigned int it_shift;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
#define DEF_SYSTEM_SIZE 0xc10
|
||||
|
||||
/* Direct access to NVRAM */
|
||||
uint32_t macio_nvram_read (void *opaque, uint32_t addr)
|
||||
uint8_t macio_nvram_read(MacIONVRAMState *s, uint32_t addr)
|
||||
{
|
||||
MacIONVRAMState *s = opaque;
|
||||
uint32_t ret;
|
||||
|
||||
if (addr < s->size)
|
||||
if (addr < s->size) {
|
||||
ret = s->data[addr];
|
||||
else
|
||||
} else {
|
||||
ret = -1;
|
||||
NVR_DPRINTF("read addr %04x val %x\n", addr, ret);
|
||||
}
|
||||
NVR_DPRINTF("read addr %04" PRIx32 " val %" PRIx8 "\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val)
|
||||
void macio_nvram_write(MacIONVRAMState *s, uint32_t addr, uint8_t val)
|
||||
{
|
||||
MacIONVRAMState *s = opaque;
|
||||
|
||||
NVR_DPRINTF("write addr %04x val %x\n", addr, val);
|
||||
if (addr < s->size)
|
||||
NVR_DPRINTF("write addr %04" PRIx32 " val %" PRIx8 "\n", addr, val);
|
||||
if (addr < s->size) {
|
||||
s->data[addr] = val;
|
||||
}
|
||||
}
|
||||
|
||||
/* macio style NVRAM device */
|
||||
@@ -78,7 +70,7 @@ static void macio_nvram_writeb(void *opaque, hwaddr addr,
|
||||
|
||||
addr = (addr >> s->it_shift) & (s->size - 1);
|
||||
s->data[addr] = value;
|
||||
NVR_DPRINTF("writeb addr %04x val %x\n", (int)addr, value);
|
||||
NVR_DPRINTF("writeb addr %04" PHYS_PRIx " val %" PRIx64 "\n", addr, value);
|
||||
}
|
||||
|
||||
static uint64_t macio_nvram_readb(void *opaque, hwaddr addr,
|
||||
@@ -97,7 +89,7 @@ static uint64_t macio_nvram_readb(void *opaque, hwaddr addr,
|
||||
static const MemoryRegionOps macio_nvram_ops = {
|
||||
.read = macio_nvram_readb,
|
||||
.write = macio_nvram_writeb,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_macio_nvram = {
|
||||
@@ -112,32 +104,56 @@ static const VMStateDescription vmstate_macio_nvram = {
|
||||
};
|
||||
|
||||
|
||||
static void macio_nvram_reset(void *opaque)
|
||||
static void macio_nvram_reset(DeviceState *dev)
|
||||
{
|
||||
}
|
||||
|
||||
MacIONVRAMState *macio_nvram_init (hwaddr size,
|
||||
unsigned int it_shift)
|
||||
static void macio_nvram_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
MacIONVRAMState *s;
|
||||
SysBusDevice *d = SYS_BUS_DEVICE(dev);
|
||||
MacIONVRAMState *s = MACIO_NVRAM(dev);
|
||||
|
||||
s = g_malloc0(sizeof(MacIONVRAMState));
|
||||
s->data = g_malloc0(size);
|
||||
s->size = size;
|
||||
s->it_shift = it_shift;
|
||||
s->data = g_malloc0(s->size);
|
||||
|
||||
memory_region_init_io(&s->mem, &macio_nvram_ops, s, "macio-nvram",
|
||||
size << it_shift);
|
||||
vmstate_register(NULL, -1, &vmstate_macio_nvram, s);
|
||||
qemu_register_reset(macio_nvram_reset, s);
|
||||
|
||||
return s;
|
||||
s->size << s->it_shift);
|
||||
sysbus_init_mmio(d, &s->mem);
|
||||
}
|
||||
|
||||
void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
|
||||
hwaddr mem_base)
|
||||
static void macio_nvram_unrealizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
memory_region_add_subregion(bar, mem_base, &s->mem);
|
||||
MacIONVRAMState *s = MACIO_NVRAM(dev);
|
||||
|
||||
g_free(s->data);
|
||||
}
|
||||
|
||||
static Property macio_nvram_properties[] = {
|
||||
DEFINE_PROP_UINT32("size", MacIONVRAMState, size, 0),
|
||||
DEFINE_PROP_UINT32("it_shift", MacIONVRAMState, it_shift, 0),
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
static void macio_nvram_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
dc->realize = macio_nvram_realizefn;
|
||||
dc->unrealize = macio_nvram_unrealizefn;
|
||||
dc->reset = macio_nvram_reset;
|
||||
dc->vmsd = &vmstate_macio_nvram;
|
||||
dc->props = macio_nvram_properties;
|
||||
}
|
||||
|
||||
static const TypeInfo macio_nvram_type_info = {
|
||||
.name = TYPE_MACIO_NVRAM,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(MacIONVRAMState),
|
||||
.class_init = macio_nvram_class_init,
|
||||
};
|
||||
|
||||
static void macio_nvram_register_types(void)
|
||||
{
|
||||
type_register_static(&macio_nvram_type_info);
|
||||
}
|
||||
|
||||
/* Set up a system OpenBIOS NVRAM partition */
|
||||
@@ -176,3 +192,5 @@ void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len)
|
||||
end = len;
|
||||
OpenBIOS_finish_partition(part_header, end - start);
|
||||
}
|
||||
|
||||
type_init(macio_nvram_register_types)
|
||||
|
||||
+228
-63
@@ -23,118 +23,283 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "hw.h"
|
||||
#include "ppc_mac.h"
|
||||
#include "ppc/mac.h"
|
||||
#include "pci/pci.h"
|
||||
#include "mac_dbdma.h"
|
||||
#include "escc.h"
|
||||
|
||||
#define TYPE_MACIO "macio"
|
||||
#define MACIO(obj) OBJECT_CHECK(MacIOState, (obj), TYPE_MACIO)
|
||||
|
||||
typedef struct MacIOState
|
||||
{
|
||||
/*< private >*/
|
||||
PCIDevice parent;
|
||||
int is_oldworld;
|
||||
/*< public >*/
|
||||
|
||||
MemoryRegion bar;
|
||||
CUDAState cuda;
|
||||
void *dbdma;
|
||||
MemoryRegion *pic_mem;
|
||||
MemoryRegion *dbdma_mem;
|
||||
MemoryRegion *cuda_mem;
|
||||
MemoryRegion *escc_mem;
|
||||
void *nvram;
|
||||
int nb_ide;
|
||||
MemoryRegion *ide_mem[4];
|
||||
} MacIOState;
|
||||
|
||||
#define OLDWORLD_MACIO(obj) \
|
||||
OBJECT_CHECK(OldWorldMacIOState, (obj), TYPE_OLDWORLD_MACIO)
|
||||
|
||||
typedef struct OldWorldMacIOState {
|
||||
/*< private >*/
|
||||
MacIOState parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
qemu_irq irqs[3];
|
||||
|
||||
MacIONVRAMState nvram;
|
||||
MACIOIDEState ide;
|
||||
} OldWorldMacIOState;
|
||||
|
||||
#define NEWWORLD_MACIO(obj) \
|
||||
OBJECT_CHECK(NewWorldMacIOState, (obj), TYPE_NEWWORLD_MACIO)
|
||||
|
||||
typedef struct NewWorldMacIOState {
|
||||
/*< private >*/
|
||||
MacIOState parent_obj;
|
||||
/*< public >*/
|
||||
qemu_irq irqs[5];
|
||||
MACIOIDEState ide[2];
|
||||
} NewWorldMacIOState;
|
||||
|
||||
static void macio_bar_setup(MacIOState *macio_state)
|
||||
{
|
||||
int i;
|
||||
MemoryRegion *bar = &macio_state->bar;
|
||||
|
||||
memory_region_init(bar, "macio", 0x80000);
|
||||
if (macio_state->pic_mem) {
|
||||
if (macio_state->is_oldworld) {
|
||||
/* Heathrow PIC */
|
||||
memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem);
|
||||
} else {
|
||||
/* OpenPIC */
|
||||
memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem);
|
||||
}
|
||||
}
|
||||
if (macio_state->dbdma_mem) {
|
||||
memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
|
||||
}
|
||||
if (macio_state->escc_mem) {
|
||||
memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
|
||||
}
|
||||
if (macio_state->cuda_mem) {
|
||||
memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
|
||||
}
|
||||
for (i = 0; i < macio_state->nb_ide; i++) {
|
||||
if (macio_state->ide_mem[i]) {
|
||||
memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000),
|
||||
macio_state->ide_mem[i]);
|
||||
}
|
||||
}
|
||||
if (macio_state->nvram != NULL)
|
||||
macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
|
||||
}
|
||||
|
||||
static int macio_initfn(PCIDevice *d)
|
||||
static int macio_common_initfn(PCIDevice *d)
|
||||
{
|
||||
MacIOState *s = MACIO(d);
|
||||
SysBusDevice *sysbus_dev;
|
||||
int ret;
|
||||
|
||||
d->config[0x3d] = 0x01; // interrupt on pin 1
|
||||
|
||||
ret = qdev_init(DEVICE(&s->cuda));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
|
||||
memory_region_add_subregion(&s->bar, 0x16000,
|
||||
sysbus_mmio_get_region(sysbus_dev, 0));
|
||||
|
||||
macio_bar_setup(s);
|
||||
pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int macio_oldworld_initfn(PCIDevice *d)
|
||||
{
|
||||
MacIOState *s = MACIO(d);
|
||||
OldWorldMacIOState *os = OLDWORLD_MACIO(d);
|
||||
SysBusDevice *sysbus_dev;
|
||||
int ret = macio_common_initfn(d);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
|
||||
sysbus_connect_irq(sysbus_dev, 0, os->irqs[0]);
|
||||
|
||||
ret = qdev_init(DEVICE(&os->nvram));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
sysbus_dev = SYS_BUS_DEVICE(&os->nvram);
|
||||
memory_region_add_subregion(&s->bar, 0x60000,
|
||||
sysbus_mmio_get_region(sysbus_dev, 0));
|
||||
pmac_format_nvram_partition(&os->nvram, os->nvram.size);
|
||||
|
||||
if (s->pic_mem) {
|
||||
/* Heathrow PIC */
|
||||
memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem);
|
||||
}
|
||||
|
||||
sysbus_dev = SYS_BUS_DEVICE(&os->ide);
|
||||
sysbus_connect_irq(sysbus_dev, 0, os->irqs[1]);
|
||||
sysbus_connect_irq(sysbus_dev, 1, os->irqs[2]);
|
||||
macio_ide_register_dma(&os->ide, s->dbdma, 0x16);
|
||||
ret = qdev_init(DEVICE(&os->ide));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void macio_oldworld_init(Object *obj)
|
||||
{
|
||||
MacIOState *s = MACIO(obj);
|
||||
OldWorldMacIOState *os = OLDWORLD_MACIO(obj);
|
||||
DeviceState *dev;
|
||||
|
||||
qdev_init_gpio_out(DEVICE(obj), os->irqs, ARRAY_SIZE(os->irqs));
|
||||
|
||||
object_initialize(&os->nvram, TYPE_MACIO_NVRAM);
|
||||
dev = DEVICE(&os->nvram);
|
||||
qdev_prop_set_uint32(dev, "size", 0x2000);
|
||||
qdev_prop_set_uint32(dev, "it_shift", 4);
|
||||
|
||||
object_initialize(&os->ide, TYPE_MACIO_IDE);
|
||||
qdev_set_parent_bus(DEVICE(&os->ide), sysbus_get_default());
|
||||
memory_region_add_subregion(&s->bar, 0x1f000 + (1 * 0x1000), &os->ide.mem);
|
||||
object_property_add_child(obj, "ide", OBJECT(&os->ide), NULL);
|
||||
}
|
||||
|
||||
static int macio_newworld_initfn(PCIDevice *d)
|
||||
{
|
||||
MacIOState *s = MACIO(d);
|
||||
NewWorldMacIOState *ns = NEWWORLD_MACIO(d);
|
||||
SysBusDevice *sysbus_dev;
|
||||
int ret = macio_common_initfn(d);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
|
||||
sysbus_connect_irq(sysbus_dev, 0, ns->irqs[0]);
|
||||
|
||||
if (s->pic_mem) {
|
||||
/* OpenPIC */
|
||||
memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem);
|
||||
}
|
||||
|
||||
sysbus_dev = SYS_BUS_DEVICE(&ns->ide[0]);
|
||||
sysbus_connect_irq(sysbus_dev, 0, ns->irqs[1]);
|
||||
sysbus_connect_irq(sysbus_dev, 1, ns->irqs[2]);
|
||||
macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x16);
|
||||
ret = qdev_init(DEVICE(&ns->ide[0]));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
sysbus_dev = SYS_BUS_DEVICE(&ns->ide[1]);
|
||||
sysbus_connect_irq(sysbus_dev, 0, ns->irqs[3]);
|
||||
sysbus_connect_irq(sysbus_dev, 1, ns->irqs[4]);
|
||||
macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x1a);
|
||||
ret = qdev_init(DEVICE(&ns->ide[1]));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void macio_newworld_init(Object *obj)
|
||||
{
|
||||
MacIOState *s = MACIO(obj);
|
||||
NewWorldMacIOState *ns = NEWWORLD_MACIO(obj);
|
||||
int i;
|
||||
gchar *name;
|
||||
|
||||
qdev_init_gpio_out(DEVICE(obj), ns->irqs, ARRAY_SIZE(ns->irqs));
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
object_initialize(&ns->ide[i], TYPE_MACIO_IDE);
|
||||
qdev_set_parent_bus(DEVICE(&ns->ide[i]), sysbus_get_default());
|
||||
memory_region_add_subregion(&s->bar, 0x1f000 + ((i + 1) * 0x1000),
|
||||
&ns->ide[i].mem);
|
||||
name = g_strdup_printf("ide[%i]", i);
|
||||
object_property_add_child(obj, name, OBJECT(&ns->ide[i]), NULL);
|
||||
g_free(name);
|
||||
}
|
||||
}
|
||||
|
||||
static void macio_instance_init(Object *obj)
|
||||
{
|
||||
MacIOState *s = MACIO(obj);
|
||||
MemoryRegion *dbdma_mem;
|
||||
|
||||
memory_region_init(&s->bar, "macio", 0x80000);
|
||||
|
||||
object_initialize(&s->cuda, TYPE_CUDA);
|
||||
qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default());
|
||||
object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL);
|
||||
|
||||
s->dbdma = DBDMA_init(&dbdma_mem);
|
||||
memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem);
|
||||
}
|
||||
|
||||
static void macio_oldworld_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc);
|
||||
|
||||
pdc->init = macio_oldworld_initfn;
|
||||
pdc->device_id = PCI_DEVICE_ID_APPLE_343S1201;
|
||||
}
|
||||
|
||||
static void macio_newworld_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc);
|
||||
|
||||
pdc->init = macio_newworld_initfn;
|
||||
pdc->device_id = PCI_DEVICE_ID_APPLE_UNI_N_KEYL;
|
||||
}
|
||||
|
||||
static void macio_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = macio_initfn;
|
||||
k->vendor_id = PCI_VENDOR_ID_APPLE;
|
||||
k->class_id = PCI_CLASS_OTHERS << 8;
|
||||
}
|
||||
|
||||
static const TypeInfo macio_info = {
|
||||
.name = "macio",
|
||||
static const TypeInfo macio_oldworld_type_info = {
|
||||
.name = TYPE_OLDWORLD_MACIO,
|
||||
.parent = TYPE_MACIO,
|
||||
.instance_size = sizeof(OldWorldMacIOState),
|
||||
.instance_init = macio_oldworld_init,
|
||||
.class_init = macio_oldworld_class_init,
|
||||
};
|
||||
|
||||
static const TypeInfo macio_newworld_type_info = {
|
||||
.name = TYPE_NEWWORLD_MACIO,
|
||||
.parent = TYPE_MACIO,
|
||||
.instance_size = sizeof(NewWorldMacIOState),
|
||||
.instance_init = macio_newworld_init,
|
||||
.class_init = macio_newworld_class_init,
|
||||
};
|
||||
|
||||
static const TypeInfo macio_type_info = {
|
||||
.name = TYPE_MACIO,
|
||||
.parent = TYPE_PCI_DEVICE,
|
||||
.instance_size = sizeof(MacIOState),
|
||||
.instance_init = macio_instance_init,
|
||||
.abstract = true,
|
||||
.class_init = macio_class_init,
|
||||
};
|
||||
|
||||
static void macio_register_types(void)
|
||||
{
|
||||
type_register_static(&macio_info);
|
||||
type_register_static(&macio_type_info);
|
||||
type_register_static(&macio_oldworld_type_info);
|
||||
type_register_static(&macio_newworld_type_info);
|
||||
}
|
||||
|
||||
type_init(macio_register_types)
|
||||
|
||||
void macio_init (PCIBus *bus, int device_id, int is_oldworld,
|
||||
MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
|
||||
MemoryRegion *cuda_mem, void *nvram,
|
||||
int nb_ide, MemoryRegion **ide_mem,
|
||||
MemoryRegion *escc_mem)
|
||||
void macio_init(PCIDevice *d,
|
||||
MemoryRegion *pic_mem,
|
||||
MemoryRegion *escc_mem)
|
||||
{
|
||||
PCIDevice *d;
|
||||
MacIOState *macio_state;
|
||||
int i;
|
||||
MacIOState *macio_state = MACIO(d);
|
||||
|
||||
d = pci_create_simple(bus, -1, "macio");
|
||||
|
||||
macio_state = DO_UPCAST(MacIOState, parent, d);
|
||||
macio_state->is_oldworld = is_oldworld;
|
||||
macio_state->pic_mem = pic_mem;
|
||||
macio_state->dbdma_mem = dbdma_mem;
|
||||
macio_state->cuda_mem = cuda_mem;
|
||||
macio_state->escc_mem = escc_mem;
|
||||
macio_state->nvram = nvram;
|
||||
if (nb_ide > 4)
|
||||
nb_ide = 4;
|
||||
macio_state->nb_ide = nb_ide;
|
||||
for (i = 0; i < nb_ide; i++)
|
||||
macio_state->ide_mem[i] = ide_mem[i];
|
||||
for (; i < 4; i++)
|
||||
macio_state->ide_mem[i] = NULL;
|
||||
/* Note: this code is strongly inspirated from the corresponding code
|
||||
in PearPC */
|
||||
|
||||
pci_config_set_device_id(d->config, device_id);
|
||||
|
||||
macio_bar_setup(macio_state);
|
||||
pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
|
||||
qdev_init_nofail(DEVICE(d));
|
||||
}
|
||||
|
||||
+246
-127
File diff suppressed because it is too large
Load Diff
@@ -13,5 +13,6 @@ enum {
|
||||
|
||||
#define OPENPIC_MODEL_RAVEN 0
|
||||
#define OPENPIC_MODEL_FSL_MPIC_20 1
|
||||
#define OPENPIC_MODEL_FSL_MPIC_42 2
|
||||
|
||||
#endif /* __OPENPIC_H__ */
|
||||
|
||||
@@ -3,10 +3,6 @@ obj-y = ppc.o ppc_booke.o
|
||||
# PREP target
|
||||
obj-y += mc146818rtc.o
|
||||
obj-y += ppc_prep.o
|
||||
# OldWorld PowerMac
|
||||
obj-y += ppc_oldworld.o
|
||||
# NewWorld PowerMac
|
||||
obj-y += ppc_newworld.o
|
||||
# IBM pSeries (sPAPR)
|
||||
obj-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
|
||||
obj-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o
|
||||
@@ -28,4 +24,9 @@ obj-y += xilinx_ethlite.o
|
||||
|
||||
obj-y := $(addprefix ../,$(obj-y))
|
||||
|
||||
# OldWorld PowerMac
|
||||
obj-y += mac_oldworld.o
|
||||
# NewWorld PowerMac
|
||||
obj-y += mac_newworld.o
|
||||
# e500
|
||||
obj-$(CONFIG_FDT) += e500.o mpc8544ds.o e500plat.o
|
||||
|
||||
+3
-3
@@ -297,7 +297,7 @@ static int ppce500_load_device_tree(CPUPPCState *env,
|
||||
snprintf(mpic, sizeof(mpic), "%s/pic@%llx", soc, MPC8544_MPIC_REGS_OFFSET);
|
||||
qemu_devtree_add_subnode(fdt, mpic);
|
||||
qemu_devtree_setprop_string(fdt, mpic, "device_type", "open-pic");
|
||||
qemu_devtree_setprop_string(fdt, mpic, "compatible", "chrp,open-pic");
|
||||
qemu_devtree_setprop_string(fdt, mpic, "compatible", "fsl,mpic");
|
||||
qemu_devtree_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_OFFSET,
|
||||
0x40000);
|
||||
qemu_devtree_setprop_cell(fdt, mpic, "#address-cells", 0);
|
||||
@@ -505,7 +505,7 @@ void ppce500_init(PPCE500Params *params)
|
||||
irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
|
||||
env->spr[SPR_BOOKE_PIR] = cs->cpu_index = i;
|
||||
env->mpic_iack = MPC8544_CCSRBAR_BASE +
|
||||
MPC8544_MPIC_REGS_OFFSET + 0x200A0;
|
||||
MPC8544_MPIC_REGS_OFFSET + 0xa0;
|
||||
|
||||
ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500);
|
||||
|
||||
@@ -545,7 +545,7 @@ void ppce500_init(PPCE500Params *params)
|
||||
mpic = g_new(qemu_irq, 256);
|
||||
dev = qdev_create(NULL, "openpic");
|
||||
qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus);
|
||||
qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_FSL_MPIC_20);
|
||||
qdev_prop_set_uint32(dev, "model", params->mpic_version);
|
||||
qdev_init_nofail(dev);
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ typedef struct PPCE500Params {
|
||||
|
||||
/* required -- must at least add toplevel board compatible */
|
||||
void (*fixup_devtree)(struct PPCE500Params *params, void *fdt);
|
||||
|
||||
int mpic_version;
|
||||
} PPCE500Params;
|
||||
|
||||
void ppce500_init(PPCE500Params *params);
|
||||
|
||||
+3
-1
@@ -15,6 +15,7 @@
|
||||
#include "../boards.h"
|
||||
#include "sysemu/device_tree.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/openpic.h"
|
||||
|
||||
static void e500plat_fixup_devtree(PPCE500Params *params, void *fdt)
|
||||
{
|
||||
@@ -44,6 +45,7 @@ static void e500plat_init(QEMUMachineInitArgs *args)
|
||||
.pci_first_slot = 0x1,
|
||||
.pci_nr_slots = PCI_SLOT_MAX - 1,
|
||||
.fixup_devtree = e500plat_fixup_devtree,
|
||||
.mpic_version = OPENPIC_MODEL_FSL_MPIC_42,
|
||||
};
|
||||
|
||||
ppce500_init(¶ms);
|
||||
@@ -53,7 +55,7 @@ static QEMUMachine e500plat_machine = {
|
||||
.name = "ppce500",
|
||||
.desc = "generic paravirt e500 platform",
|
||||
.init = e500plat_init,
|
||||
.max_cpus = 15,
|
||||
.max_cpus = 32,
|
||||
DEFAULT_MACHINE_OPTIONS,
|
||||
};
|
||||
|
||||
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* QEMU PowerMac emulation shared definitions and prototypes
|
||||
*
|
||||
* Copyright (c) 2004-2007 Fabrice Bellard
|
||||
* Copyright (c) 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
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#if !defined(__PPC_MAC_H__)
|
||||
#define __PPC_MAC_H__
|
||||
|
||||
#include "exec/memory.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/ide/internal.h"
|
||||
#include "hw/adb.h"
|
||||
|
||||
/* SMP is not enabled, for now */
|
||||
#define MAX_CPUS 1
|
||||
|
||||
#define BIOS_SIZE (1024 * 1024)
|
||||
#define BIOS_FILENAME "ppc_rom.bin"
|
||||
#define NVRAM_SIZE 0x2000
|
||||
#define PROM_FILENAME "openbios-ppc"
|
||||
#define PROM_ADDR 0xfff00000
|
||||
|
||||
#define KERNEL_LOAD_ADDR 0x01000000
|
||||
#define KERNEL_GAP 0x00100000
|
||||
|
||||
#define ESCC_CLOCK 3686400
|
||||
|
||||
/* Cuda */
|
||||
#define TYPE_CUDA "cuda"
|
||||
#define CUDA(obj) OBJECT_CHECK(CUDAState, (obj), TYPE_CUDA)
|
||||
|
||||
/**
|
||||
* CUDATimer:
|
||||
* @counter_value: counter value at load time
|
||||
*/
|
||||
typedef struct CUDATimer {
|
||||
int index;
|
||||
uint16_t latch;
|
||||
uint16_t counter_value;
|
||||
int64_t load_time;
|
||||
int64_t next_irq_time;
|
||||
QEMUTimer *timer;
|
||||
} CUDATimer;
|
||||
|
||||
/**
|
||||
* CUDAState:
|
||||
* @b: B-side data
|
||||
* @a: A-side data
|
||||
* @dirb: B-side direction (1=output)
|
||||
* @dira: A-side direction (1=output)
|
||||
* @sr: Shift register
|
||||
* @acr: Auxiliary control register
|
||||
* @pcr: Peripheral control register
|
||||
* @ifr: Interrupt flag register
|
||||
* @ier: Interrupt enable register
|
||||
* @anh: A-side data, no handshake
|
||||
* @last_b: last value of B register
|
||||
* @last_acr: last value of ACR register
|
||||
*/
|
||||
typedef struct CUDAState {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
MemoryRegion mem;
|
||||
/* cuda registers */
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
uint8_t dirb;
|
||||
uint8_t dira;
|
||||
uint8_t sr;
|
||||
uint8_t acr;
|
||||
uint8_t pcr;
|
||||
uint8_t ifr;
|
||||
uint8_t ier;
|
||||
uint8_t anh;
|
||||
|
||||
ADBBusState adb_bus;
|
||||
CUDATimer timers[2];
|
||||
|
||||
uint32_t tick_offset;
|
||||
|
||||
uint8_t last_b;
|
||||
uint8_t last_acr;
|
||||
|
||||
int data_in_size;
|
||||
int data_in_index;
|
||||
int data_out_index;
|
||||
|
||||
qemu_irq irq;
|
||||
uint8_t autopoll;
|
||||
uint8_t data_in[128];
|
||||
uint8_t data_out[16];
|
||||
QEMUTimer *adb_poll_timer;
|
||||
} CUDAState;
|
||||
|
||||
/* MacIO */
|
||||
#define TYPE_OLDWORLD_MACIO "macio-oldworld"
|
||||
#define TYPE_NEWWORLD_MACIO "macio-newworld"
|
||||
|
||||
#define TYPE_MACIO_IDE "macio-ide"
|
||||
#define MACIO_IDE(obj) OBJECT_CHECK(MACIOIDEState, (obj), TYPE_MACIO_IDE)
|
||||
|
||||
typedef struct MACIOIDEState {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
qemu_irq irq;
|
||||
qemu_irq dma_irq;
|
||||
|
||||
MemoryRegion mem;
|
||||
IDEBus bus;
|
||||
BlockDriverAIOCB *aiocb;
|
||||
} MACIOIDEState;
|
||||
|
||||
void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table);
|
||||
void macio_ide_register_dma(MACIOIDEState *ide, void *dbdma, int channel);
|
||||
|
||||
void macio_init(PCIDevice *dev,
|
||||
MemoryRegion *pic_mem,
|
||||
MemoryRegion *escc_mem);
|
||||
|
||||
/* Heathrow PIC */
|
||||
qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
|
||||
int nb_cpus, qemu_irq **irqs);
|
||||
|
||||
/* Grackle PCI */
|
||||
#define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost"
|
||||
PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
|
||||
MemoryRegion *address_space_mem,
|
||||
MemoryRegion *address_space_io);
|
||||
|
||||
/* UniNorth PCI */
|
||||
PCIBus *pci_pmac_init(qemu_irq *pic,
|
||||
MemoryRegion *address_space_mem,
|
||||
MemoryRegion *address_space_io);
|
||||
PCIBus *pci_pmac_u3_init(qemu_irq *pic,
|
||||
MemoryRegion *address_space_mem,
|
||||
MemoryRegion *address_space_io);
|
||||
|
||||
/* Mac NVRAM */
|
||||
#define TYPE_MACIO_NVRAM "macio-nvram"
|
||||
#define MACIO_NVRAM(obj) \
|
||||
OBJECT_CHECK(MacIONVRAMState, (obj), TYPE_MACIO_NVRAM)
|
||||
|
||||
typedef struct MacIONVRAMState {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
uint32_t size;
|
||||
uint32_t it_shift;
|
||||
|
||||
MemoryRegion mem;
|
||||
uint8_t *data;
|
||||
} MacIONVRAMState;
|
||||
|
||||
void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
|
||||
uint8_t macio_nvram_read(MacIONVRAMState *s, uint32_t addr);
|
||||
void macio_nvram_write(MacIONVRAMState *s, uint32_t addr, uint8_t val);
|
||||
#endif /* !defined(__PPC_MAC_H__) */
|
||||
@@ -46,28 +46,28 @@
|
||||
* 0001:05:0c.0 IDE interface [0101]: Broadcom K2 SATA [1166:0240]
|
||||
*
|
||||
*/
|
||||
#include "hw.h"
|
||||
#include "ppc.h"
|
||||
#include "ppc_mac.h"
|
||||
#include "adb.h"
|
||||
#include "mac_dbdma.h"
|
||||
#include "nvram.h"
|
||||
#include "pci/pci.h"
|
||||
#include "hw/hw.h"
|
||||
#include "hw/ppc.h"
|
||||
#include "hw/ppc/mac.h"
|
||||
#include "hw/adb.h"
|
||||
#include "hw/mac_dbdma.h"
|
||||
#include "hw/nvram.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "net/net.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "boards.h"
|
||||
#include "fw_cfg.h"
|
||||
#include "escc.h"
|
||||
#include "openpic.h"
|
||||
#include "ide.h"
|
||||
#include "loader.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/fw_cfg.h"
|
||||
#include "hw/escc.h"
|
||||
#include "hw/openpic.h"
|
||||
#include "hw/ide.h"
|
||||
#include "hw/loader.h"
|
||||
#include "elf.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "kvm_ppc.h"
|
||||
#include "hw/usb.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "sysbus.h"
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
#define MAX_IDE_BUS 2
|
||||
#define CFG_ADDR 0xf0000510
|
||||
@@ -147,15 +147,16 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
||||
hwaddr kernel_base, initrd_base, cmdline_base = 0;
|
||||
long kernel_size, initrd_size;
|
||||
PCIBus *pci_bus;
|
||||
PCIDevice *macio;
|
||||
MACIOIDEState *macio_ide;
|
||||
BusState *adb_bus;
|
||||
MacIONVRAMState *nvr;
|
||||
int bios_size;
|
||||
MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
|
||||
MemoryRegion *pic_mem, *escc_mem;
|
||||
MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *ide_mem[3];
|
||||
int ppc_boot_device;
|
||||
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
||||
void *fw_cfg;
|
||||
void *dbdma;
|
||||
int machine_arch;
|
||||
SysBusDevice *s;
|
||||
DeviceState *dev;
|
||||
@@ -362,20 +363,31 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
||||
pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
|
||||
|
||||
ide_drive_get(hd, MAX_IDE_BUS);
|
||||
dbdma = DBDMA_init(&dbdma_mem);
|
||||
|
||||
macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO);
|
||||
dev = DEVICE(macio);
|
||||
qdev_connect_gpio_out(dev, 0, pic[0x19]); /* CUDA */
|
||||
qdev_connect_gpio_out(dev, 1, pic[0x0d]); /* IDE */
|
||||
qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */
|
||||
qdev_connect_gpio_out(dev, 3, pic[0x0e]); /* IDE */
|
||||
qdev_connect_gpio_out(dev, 4, pic[0x02]); /* IDE DMA */
|
||||
macio_init(macio, pic_mem, escc_bar);
|
||||
|
||||
/* We only emulate 2 out of 3 IDE controllers for now */
|
||||
ide_mem[0] = NULL;
|
||||
ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
|
||||
ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
|
||||
macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
|
||||
"ide[0]"));
|
||||
macio_ide_init_drives(macio_ide, hd);
|
||||
|
||||
cuda_init(&cuda_mem, pic[0x19]);
|
||||
macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
|
||||
"ide[1]"));
|
||||
macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
|
||||
|
||||
adb_kbd_init(&adb_bus);
|
||||
adb_mouse_init(&adb_bus);
|
||||
|
||||
macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
|
||||
dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar);
|
||||
dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
|
||||
adb_bus = qdev_get_child_bus(dev, "adb.0");
|
||||
dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD);
|
||||
qdev_init_nofail(dev);
|
||||
dev = qdev_create(adb_bus, TYPE_ADB_MOUSE);
|
||||
qdev_init_nofail(dev);
|
||||
|
||||
if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
|
||||
pci_create_simple(pci_bus, -1, "pci-ohci");
|
||||
@@ -391,9 +403,13 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
||||
graphic_depth = 15;
|
||||
|
||||
/* The NewWorld NVRAM is not located in the MacIO device */
|
||||
nvr = macio_nvram_init(0x2000, 1);
|
||||
dev = qdev_create(NULL, TYPE_MACIO_NVRAM);
|
||||
qdev_prop_set_uint32(dev, "size", 0x2000);
|
||||
qdev_prop_set_uint32(dev, "it_shift", 1);
|
||||
qdev_init_nofail(dev);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xFFF04000);
|
||||
nvr = MACIO_NVRAM(dev);
|
||||
pmac_format_nvram_partition(nvr, 0x2000);
|
||||
macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000);
|
||||
/* No PCI init: the BIOS will do it */
|
||||
|
||||
fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
|
||||
@@ -23,21 +23,20 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "hw.h"
|
||||
#include "ppc.h"
|
||||
#include "ppc_mac.h"
|
||||
#include "adb.h"
|
||||
#include "mac_dbdma.h"
|
||||
#include "nvram.h"
|
||||
#include "hw/hw.h"
|
||||
#include "hw/ppc.h"
|
||||
#include "mac.h"
|
||||
#include "hw/adb.h"
|
||||
#include "hw/nvram.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "net/net.h"
|
||||
#include "isa.h"
|
||||
#include "pci/pci.h"
|
||||
#include "boards.h"
|
||||
#include "fw_cfg.h"
|
||||
#include "escc.h"
|
||||
#include "ide.h"
|
||||
#include "loader.h"
|
||||
#include "hw/isa.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/fw_cfg.h"
|
||||
#include "hw/escc.h"
|
||||
#include "hw/ide.h"
|
||||
#include "hw/loader.h"
|
||||
#include "elf.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "kvm_ppc.h"
|
||||
@@ -90,14 +89,16 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
|
||||
uint32_t kernel_base, initrd_base, cmdline_base = 0;
|
||||
int32_t kernel_size, initrd_size;
|
||||
PCIBus *pci_bus;
|
||||
MacIONVRAMState *nvr;
|
||||
PCIDevice *macio;
|
||||
MACIOIDEState *macio_ide;
|
||||
DeviceState *dev;
|
||||
BusState *adb_bus;
|
||||
int bios_size;
|
||||
MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
|
||||
MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[2];
|
||||
MemoryRegion *pic_mem;
|
||||
MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1);
|
||||
uint16_t ppc_boot_device;
|
||||
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
||||
void *fw_cfg;
|
||||
void *dbdma;
|
||||
|
||||
linux_boot = (kernel_filename != NULL);
|
||||
|
||||
@@ -263,10 +264,17 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
|
||||
|
||||
ide_drive_get(hd, MAX_IDE_BUS);
|
||||
|
||||
macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
|
||||
dev = DEVICE(macio);
|
||||
qdev_connect_gpio_out(dev, 0, pic[0x12]); /* CUDA */
|
||||
qdev_connect_gpio_out(dev, 1, pic[0x0D]); /* IDE */
|
||||
qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */
|
||||
macio_init(macio, pic_mem, escc_bar);
|
||||
|
||||
/* First IDE channel is a MAC IDE on the MacIO bus */
|
||||
dbdma = DBDMA_init(&dbdma_mem);
|
||||
ide_mem[0] = NULL;
|
||||
ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
|
||||
macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
|
||||
"ide"));
|
||||
macio_ide_init_drives(macio_ide, hd);
|
||||
|
||||
/* Second IDE channel is a CMD646 on the PCI bus */
|
||||
hd[0] = hd[MAX_IDE_DEVS];
|
||||
@@ -274,17 +282,12 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
|
||||
hd[3] = hd[2] = NULL;
|
||||
pci_cmd646_ide_init(pci_bus, hd, 0);
|
||||
|
||||
/* cuda also initialize ADB */
|
||||
cuda_init(&cuda_mem, pic[0x12]);
|
||||
|
||||
adb_kbd_init(&adb_bus);
|
||||
adb_mouse_init(&adb_bus);
|
||||
|
||||
nvr = macio_nvram_init(0x2000, 4);
|
||||
pmac_format_nvram_partition(nvr, 0x2000);
|
||||
|
||||
macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem,
|
||||
dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar);
|
||||
dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
|
||||
adb_bus = qdev_get_child_bus(dev, "adb.0");
|
||||
dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD);
|
||||
qdev_init_nofail(dev);
|
||||
dev = qdev_create(adb_bus, TYPE_ADB_MOUSE);
|
||||
qdev_init_nofail(dev);
|
||||
|
||||
if (usb_enabled(false)) {
|
||||
pci_create_simple(pci_bus, -1, "pci-ohci");
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "e500.h"
|
||||
#include "../boards.h"
|
||||
#include "sysemu/device_tree.h"
|
||||
#include "hw/openpic.h"
|
||||
|
||||
static void mpc8544ds_fixup_devtree(PPCE500Params *params, void *fdt)
|
||||
{
|
||||
@@ -43,6 +44,7 @@ static void mpc8544ds_init(QEMUMachineInitArgs *args)
|
||||
.pci_first_slot = 0x11,
|
||||
.pci_nr_slots = 2,
|
||||
.fixup_devtree = mpc8544ds_fixup_devtree,
|
||||
.mpic_version = OPENPIC_MODEL_FSL_MPIC_20,
|
||||
};
|
||||
|
||||
ppce500_init(¶ms);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user