Compare commits

...
28 Commits
Author SHA1 Message Date
Martijn de Vos fd6f1e0ed9 USB communication working 2025-02-19 19:33:07 +01:00
Martijn de Vos aa88deb054 Worked on USB/TCP 2025-02-04 20:33:40 +01:00
Martijn de Vos 328815631b Merge pull request #213 from mrcxlinux/ipod_touch_2g
Include commands for Arch Linux and it's derivatives (RUNNING.MD)
2025-01-02 09:20:51 +01:00
陈华 c5998ab084 Include commands for Arch Linux and it's derivatives 2025-01-01 17:57:06 +02:00
Martijn de Vos 1c586e8a0c Also fixed type of fsize in SPI 2024-12-25 09:46:50 +01:00
Martijn de Vos 7022646c4d Fixed gsize type 2024-12-24 09:06:06 +01:00
Martijn de Vos fa0981b602 Merge pull request #205 from devos50/brightness
Added support for brightness
2024-12-22 11:44:06 +01:00
daniilfigasystems 0cb390e281 Added support for brightness 2024-12-22 11:41:17 +01:00
Martijn de Vos 0d8014f8db Fixed path to configure 2024-12-22 10:39:03 +01:00
Martijn de Vos e241f91a5b Merge pull request #176 from Patrosi73/ipod_touch_2g
fix swapLong argument
2024-08-04 16:44:39 +02:00
PatRyk 4400b861c8 Update ipod_touch_sha1.c
fix swapLong argument
2024-08-04 16:34:49 +02:00
Martijn de Vos cae1b51a78 Merge pull request #172 from daniilfigasystems/ipod_touch_2g
Bugfix
2024-07-31 09:30:34 +02:00
daniilfigasystems a99e51abfa Format code, add more verbosity (for implementing lock screen), fixed warnings 2024-07-31 11:22:16 +09:00
daniilfigasystems ce74809f11 Rename unknown1 to render 2024-07-31 11:00:16 +09:00
daniilfigasystems ceb93afd79 Fix printf newline 2024-07-31 10:58:04 +09:00
Martijn de Vos bad3d0cc90 Merge pull request #170 from daniilfigasystems/ipod_touch_2g
Fixed bugs added new devices
2024-07-30 13:01:57 +02:00
daniilfigasystems 82b95a84a3 Add ctrl reg axis enabled check 2024-07-30 11:35:19 +09:00
daniilfigasystems 28f87fc7d6 Fixed bugs added new devices
Fixed unexpected CLCD interrupt (for now only unexcepted interrupt from mulltitouch), added audio codec skeleton, added light sensor, fixed pressing other buttons lead to crash, added kernel patch check (improves perfomance a little), added more verbosity, planning to add working wifi (need datasheet)
2024-07-30 10:22:49 +09:00
olivia1246 973b5a90ef Build on Linux (Ubuntu) (RUNNING.md) (#143)
* Update RUNNING.md

I think is good now super big thanks to https://github.com/Polytelus on https://github.com/devos50/qemu-ios/issues/92 and ChatGPT lolz

* Update RUNNING.md

thanks for pointing it out https://github.com/MrDiagnose I didnt realise that

* Update RUNNING.md

thank you everyone for the build dir recommendation

* Update RUNNING.md

a little space for easier copying I hope
2024-07-29 20:47:34 +02:00
Martijn de Vos adaea1d394 Merge pull request #122 from devos50/gpio
Generalized GPIO logic
2024-01-13 13:58:25 +01:00
Martijn de Vos 7d55fc7991 Generalized GPIO logic
As preparation for the emulation of DFU mode
2024-01-13 13:56:30 +01:00
Martijn de Vos d8e7109d35 Merge pull request #121 from thebreaddev/ipod_touch_2g
fix FPE and allow running any code
2024-01-12 16:38:26 +01:00
BreadDEV 93dbb7ad69 fix floating point exception
used code from https://github.com/devos50/qemu-ios/commit/8acdcfc48ad19ee6dfb30d7be3abcb6110cb2f25
it was on ipod_touch_1g branch but not on 2g
2024-01-12 21:38:03 +07:00
BreadDEV f7f46cc0b3 boot args modification to disable code signature check
i added "amfi_allow_any_signature=1" boot arg so you can run .app that was fakesigned with ldid -S
2024-01-11 18:16:12 +07:00
Martijn de Vos 32e2ae008a Merge pull request #109 from devos50/vol_buttons
Implemented support for volume up/down buttons
2024-01-01 21:01:44 +01:00
Martijn de Vos cde16baff0 Implemented support for volume up/down buttons
It's not doing much as the audio device is not working yet.
2024-01-01 20:59:53 +01:00
Martijn de Vos 38cebf5d0b Merge pull request #108 from ChaseKnowlden/enable-cocoa
Enable cocoa on Apple Silicon Macs
2024-01-01 10:37:27 +01:00
ChaseKnowlden c87aa5415a Enable cocoa on Apple Silicon Macs 2023-12-31 19:42:53 -05:00
33 changed files with 1335 additions and 115 deletions

No files matched your search

+20 -1
View File
@@ -2,6 +2,18 @@
This file contains the instructions on how to run the iPod Touch 2G emulator using QEMU.
Note that this is an experimental release and the functionality of the device is still limited.
Linux compatibility is currently unstable. Efforts are underway to improve it.
### Getting the Source Code
Clone the repository using the following commands:
```
git clone https://github.com/devos50/qemu-ios.git
cd qemu-ios
```
Now you can proceed with the rest of the instructions for building and running the emulator.
### Building QEMU
@@ -14,6 +26,9 @@ brew install glib ninja pixman pkg-config sdl2
# On Linux (Ubuntu)
sudo apt install make ninja-build pkg-config libssl-dev libsdl2-dev libpixman-1-dev libpixman-1-0 libglib2.0-dev
# On Linux (Arch)
sudo pacman -S --needed make ninja pkgconf openssl sdl2 pixman glib2
# On Windows (MSYS2/mingw64)
pacman -S base-devel mingw-w64-x86_64-toolchain git python ninja mingw-w64-x86_64-glib2 mingw-w64-x86_64-pixman python-setuptools mingw-w64-x86_64-SDL2
@@ -23,11 +38,15 @@ Compile QEMU by running the following commands from the root directory:
```
mkdir build
cd build
# On Intel Macs
../configure --target-list=arm-softmmu --extra-cflags=-I/usr/local/opt/openssl@3/include --extra-ldflags='-L/usr/local/opt/openssl@3/lib -lcrypto'
# On Apple Silicon Macs
../configure --enable-sdl --disable-cocoa --target-list=arm-softmmu --disable-capstone --disable-pie --disable-slirp --extra-cflags=-I/opt/homebrew/opt/openssl@3/include --extra-ldflags='-L/opt/homebrew/opt/openssl@3/lib -lcrypto'
../configure --enable-sdl --target-list=arm-softmmu --disable-capstone --disable-pie --disable-slirp --extra-cflags=-I/opt/homebrew/opt/openssl@3/include --extra-ldflags='-L/opt/homebrew/opt/openssl@3/lib -lcrypto'
# On Linux
../configure --enable-sdl --disable-cocoa --target-list=arm-softmmu --disable-capstone --disable-slirp --extra-cflags=-I/usr/include/openssl --extra-ldflags='-lcrypto' --disable-werror --enable-pie
# On Microsoft Windows (with MINGW64)
../configure --enable-sdl --disable-cocoa --target-list=arm-softmmu --disable-capstone --disable-slirp --disable-pie --extra-cflags=-I/mingw64/include/openssl --extra-ldflags='-L/mingw64/lib -lcrypto' --disable-stack-protector --disable-werror
+53 -21
View File
@@ -96,7 +96,7 @@ static void ipod_touch_memory_setup(MachineState *machine, MemoryRegion *sysmem,
// load the bootrom (vrom)
uint8_t *file_data = NULL;
unsigned long fsize;
gsize fsize;
if (g_file_get_contents(nms->bootrom_path, (char **)&file_data, &fsize, NULL)) {
allocate_ram(sysmem, "vrom", 0x0, 0x20000);
address_space_rw(nsas, VROM_MEM_BASE, MEMTXATTRS_UNSPECIFIED, (uint8_t *)file_data, fsize, 1);
@@ -187,39 +187,59 @@ static void ipod_touch_key_event(void *opaque, int keycode)
int gpio_group = 0, gpio_selector = 0;
IPodTouchMultitouchState *s = (IPodTouchMultitouchState *)opaque;
if(keycode == 25 || keycode == 153) {
if(keycode == KEY_P_DOWN || keycode == KEY_P_UP) {
// power button
gpio_group = GPIO_BUTTON_POWER_IRQ / NUM_GPIO_PINS;
gpio_selector = GPIO_BUTTON_POWER_IRQ % NUM_GPIO_PINS;
if(keycode == 25 && (s->gpio_state->gpio_state & (1 << (GPIO_BUTTON_POWER & 0xf))) == 0) {
s->gpio_state->gpio_state |= (1 << (GPIO_BUTTON_POWER & 0xf));
do_irq = true;
if(keycode == KEY_P_DOWN && gpio_is_off(s->gpio_state->gpio_state, GPIO_BUTTON_POWER)) {
gpio_set_on(s->gpio_state->gpio_state, GPIO_BUTTON_POWER);
}
else if(keycode == 153) {
s->gpio_state->gpio_state &= ~(1 << (GPIO_BUTTON_POWER & 0xf));
do_irq = true;
else if(keycode == KEY_P_UP) {
gpio_set_off(s->gpio_state->gpio_state, GPIO_BUTTON_POWER);
}
}
else if(keycode == 35 || keycode == 163) {
else if(keycode == KEY_H_DOWN || keycode == KEY_H_UP) {
// home button
gpio_group = GPIO_BUTTON_HOME_IRQ / NUM_GPIO_PINS;
gpio_selector = GPIO_BUTTON_HOME_IRQ % NUM_GPIO_PINS;
if(keycode == 35 && (s->gpio_state->gpio_state & (1 << (GPIO_BUTTON_HOME & 0xf))) == 0) {
s->gpio_state->gpio_state |= (1 << (GPIO_BUTTON_HOME & 0xf));
do_irq = true;
if(keycode == KEY_H_DOWN && gpio_is_off(s->gpio_state->gpio_state, GPIO_BUTTON_HOME)) {
gpio_set_on(s->gpio_state->gpio_state, GPIO_BUTTON_HOME);
}
else if(keycode == 163) {
s->gpio_state->gpio_state &= ~(1 << (GPIO_BUTTON_HOME & 0xf));
do_irq = true;
else if(keycode == KEY_H_UP) {
gpio_set_off(s->gpio_state->gpio_state, GPIO_BUTTON_HOME);
}
}
else if(keycode == KEY_MIN_DOWN || keycode == KEY_MIN_UP) {
// volume down button
gpio_group = GPIO_BUTTON_VOLDOWN_IRQ / NUM_GPIO_PINS;
gpio_selector = GPIO_BUTTON_VOLDOWN_IRQ % NUM_GPIO_PINS;
if(keycode == KEY_MIN_DOWN && gpio_is_off(s->gpio_state->gpio_state, GPIO_BUTTON_VOLDOWN)) {
gpio_set_on(s->gpio_state->gpio_state, GPIO_BUTTON_VOLDOWN);
}
else if(keycode == KEY_MIN_UP) {
gpio_set_off(s->gpio_state->gpio_state, GPIO_BUTTON_VOLDOWN);
}
}
else if(keycode == KEY_PLUS_DOWN || keycode == KEY_PLUS_UP) {
// volume down button
gpio_group = GPIO_BUTTON_VOLUP_IRQ / NUM_GPIO_PINS;
gpio_selector = GPIO_BUTTON_VOLUP_IRQ % NUM_GPIO_PINS;
if(keycode == KEY_PLUS_DOWN && gpio_is_off(s->gpio_state->gpio_state, GPIO_BUTTON_VOLUP)) {
gpio_set_on(s->gpio_state->gpio_state, GPIO_BUTTON_VOLUP);
}
else if(keycode == KEY_PLUS_UP) {
gpio_set_off(s->gpio_state->gpio_state, GPIO_BUTTON_VOLUP);
}
}
else return;
if(do_irq) {
s->sysic->gpio_int_status[gpio_group] |= (1 << gpio_selector);
qemu_irq_raise(s->sysic->gpio_irqs[gpio_group]);
}
s->sysic->gpio_int_status[gpio_group] |= (1 << gpio_selector);
qemu_irq_raise(s->sysic->gpio_irqs[gpio_group]);
}
static void ipod_touch_machine_init(MachineState *machine)
@@ -387,7 +407,9 @@ static void ipod_touch_machine_init(MachineState *machine)
dev = ipod_touch_init_usb_otg(s5l8900_get_irq(nms, S5L8720_USB_OTG_IRQ), s5l8720_usb_hwcfg);
synopsys_usb_state *usb_otg = S5L8900USBOTG(dev);
nms->usb_otg = usb_otg;
busdev = SYS_BUS_DEVICE(dev);
memory_region_add_subregion(sysmem, USBOTG_MEM_BASE, &nms->usb_otg->iomem);
sysbus_realize(busdev, &error_fatal);
// init two pl080 DMAC0 devices
dev = qdev_new("pl080");
@@ -423,6 +445,9 @@ static void ipod_touch_machine_init(MachineState *machine)
// init the accelerometer
I2CSlave *accelerometer = i2c_slave_create_simple(i2c_state->bus, "lis302dl", 0x1D);
// init the audio codec (disabled because unused)
// I2CSlave *audio_codec = i2c_slave_create_simple(i2c_state->bus, "cs42l58", 0x4A);
// Init I2C1
dev = qdev_new("ipodtouch.i2c");
i2c_state = IPOD_TOUCH_I2C(dev);
@@ -432,6 +457,9 @@ static void ipod_touch_machine_init(MachineState *machine)
memory_region_add_subregion(sysmem, I2C1_MEM_BASE, &i2c_state->iomem);
sysbus_realize(busdev, &error_fatal);
sysbus_connect_irq(busdev, 0, s5l8900_get_irq(nms, S5L8720_I2C1_IRQ));
// Init the light sensor
I2CSlave *isl29003dl = i2c_slave_create_simple(i2c_state->bus, "isl29003dl", 0x44);
// init the Mikey
I2CSlave *cd327mikey = i2c_slave_create_simple(i2c_state->bus, "cd3272mikey", 0x39);
@@ -507,6 +535,10 @@ static void ipod_touch_machine_init(MachineState *machine)
qemu_register_reset(ipod_touch_cpu_reset, nms);
qemu_add_kbd_event_handler(ipod_touch_key_event, spi4_state->mt);
// toggle DFU
gpio_set_on(nms->gpio_state->gpio_state, GPIO_FORCE_DFU);
nms->usb_phys_state->is_cable_connected = true;
}
static void ipod_touch_machine_class_init(ObjectClass *klass, void *data)
@@ -532,4 +564,4 @@ static void ipod_touch_machine_types(void)
type_register_static(&ipod_touch_machine_info);
}
type_init(ipod_touch_machine_types)
type_init(ipod_touch_machine_types)
+54
View File
@@ -0,0 +1,54 @@
#include "hw/arm/ipod_touch_cs42l58.h"
static int cs42l58_event(I2CSlave *i2c, enum i2c_event event)
{
return 0;
}
static uint8_t cs42l58_recv(I2CSlave *i2c)
{
CS42L58State *s = CS42L58(i2c);
printf("Reading stereo codec register %d\n", s->cmd);
switch(s->cmd) {
default:
return 0;
}
}
static int cs42l58_send(I2CSlave *i2c, uint8_t data)
{
CS42L58State *s = CS42L58(i2c);
s->cmd = data;
printf("Writing stereo codec register %d\n", s->cmd);
return 0;
}
static void cs42l58_init(Object *obj)
{
}
static void cs42l58_class_init(ObjectClass *klass, void *data)
{
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
k->event = cs42l58_event;
k->recv = cs42l58_recv;
k->send = cs42l58_send;
}
static const TypeInfo cs42l58_info = {
.name = TYPE_CS42L58,
.parent = TYPE_I2C_SLAVE,
.instance_init = cs42l58_init,
.instance_size = sizeof(CS42L58State),
.class_init = cs42l58_class_init,
};
static void cs42l58_register_types(void)
{
type_register_static(&cs42l58_info);
}
type_init(cs42l58_register_types)
+14 -7
View File
@@ -1,5 +1,7 @@
#include "hw/arm/ipod_touch_fmss.h"
uint64_t temp_storage[512];
static uint8_t find_bit_index(uint8_t num) {
int index = 0;
while (num > 1) {
@@ -24,7 +26,7 @@ static void dump_registers(IPodTouchFMSSState *s) {
static void read_nand_pages(IPodTouchFMSSState *s)
{
// boot args
const char *boot_args = "kextlog=0xfff debug=0x8 cpus=1 rd=disk0s1 serial=1 pmu-debug=0x1 io=0xffff8fff debug-usb=0xffffffff"; // if not const then overwritten
const char *boot_args = "kextlog=0xfff debug=0x8 cpus=1 rd=disk0s1 serial=1 pmu-debug=0x1 io=0xffff8fff debug-usb=0xffffffff amfi_allow_any_signature=1 -v zalloc_debug"; // if not const then overwritten
cpu_physical_memory_write(0x0ff2a584, boot_args, strlen(boot_args));
// patch iBoot - we want to inject the bluetooth MAC address which is located as sub-node of uart1 and not uart3 in the device tree...
@@ -45,7 +47,7 @@ static void read_nand_pages(IPodTouchFMSSState *s)
if(cs > 3) {
printf("CS %d invalid! (original CS: %d, reading page %d)\n", cs, og_cs, page_nr);
dump_registers(s);
//dump_registers(s);
hw_error("CS %d invalid!", cs);
}
@@ -86,7 +88,7 @@ static void read_nand_pages(IPodTouchFMSSState *s)
static uint64_t ipod_touch_fmss_read(void *opaque, hwaddr addr, unsigned size)
{
//fprintf(stderr, "%s: read from location 0x%08x\n", __func__, addr);
//fprintf(stderr, "%s: read from location 0x%08lx\n", __func__, addr);
IPodTouchFMSSState *s = (IPodTouchFMSSState *)opaque;
switch(addr)
@@ -101,8 +103,10 @@ static uint64_t ipod_touch_fmss_read(void *opaque, hwaddr addr, unsigned size)
return (0x1 << 30);
case 0xD00:
return 42;
case 0x00000C30:
return 0x1;
default:
// hw_error("%s: read invalid location 0x%08x.\n", __func__, addr);
printf("%s: read invalid location 0x%08x.\n", __func__, addr);
break;
}
return 0;
@@ -111,7 +115,7 @@ static uint64_t ipod_touch_fmss_read(void *opaque, hwaddr addr, unsigned size)
static void ipod_touch_fmss_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
{
IPodTouchFMSSState *s = (IPodTouchFMSSState *)opaque;
//printf("%s: writing 0x%08x to 0x%08x\n", __func__, val, addr);
//printf("%s: writing 0x%08lx to 0x%08lx\n", __func__, val, addr);
switch(addr) {
case 0xC00:
@@ -146,8 +150,11 @@ static void ipod_touch_fmss_write(void *opaque, hwaddr addr, uint64_t val, unsig
break;
case 0xD38:
if(s->reg_csgenrc == 0xa01) { read_nand_pages(s); }
else { printf("NAND write not suported yet!\n"); }
else { /*printf("NAND write %ld addr %ld\n", val, addr); temp_storage[addr] = val;*//*cpu_physical_memory_write(addr, val, sizeof(val)); */}
break;
default:
//printf("%s unknown write %lx to %lx\n", __func__, val, addr);
break;
}
}
+25 -3
View File
@@ -13,12 +13,14 @@ static void s5l8900_gpio_write(void *opaque, hwaddr addr, uint64_t value, unsign
static uint64_t s5l8900_gpio_read(void *opaque, hwaddr addr, unsigned size)
{
fprintf(stderr, "%s: read from location 0x%08x\n", __func__, addr);
printf("%s: read from location 0x%08x\n", __func__, addr);
IPodTouchGPIOState *s = (struct IPodTouchGPIOState *) opaque;
switch(addr) {
case 0x184: // TODO: This offset only makes sure that the GPIO triggers associated with the home/power button work correctly!!
return s->gpio_state;
case 0x4:
return 0;
case 0x24 ... 0x184:
return s->gpio_state[GPIOADDR2PAD(addr)];
default:
break;
}
@@ -26,6 +28,26 @@ static uint64_t s5l8900_gpio_read(void *opaque, hwaddr addr, unsigned size)
return 0;
}
bool gpio_is_on(uint32_t *state, uint32_t gpio)
{
return (state[GPIO2PAD(gpio)] & (1 << GPIO2PIN(gpio)));
}
bool gpio_is_off(uint32_t *state, uint32_t gpio)
{
return !gpio_is_on(state, gpio);
}
void gpio_set_on(uint32_t *state, uint32_t gpio)
{
state[GPIO2PAD(gpio)] |= (1 << GPIO2PIN(gpio));
}
void gpio_set_off(uint32_t *state, uint32_t gpio)
{
state[GPIO2PAD(gpio)] &= ~(1 << GPIO2PIN(gpio));
}
static const MemoryRegionOps gpio_ops = {
.read = s5l8900_gpio_read,
.write = s5l8900_gpio_write,
+101
View File
@@ -0,0 +1,101 @@
#include "hw/arm/ipod_touch_isl29003dl.h"
static int isl29003dl_event(I2CSlave *i2c, enum i2c_event event)
{
ISL29003DLState *s = ISL29003DL(i2c);
printf("%s Got event %d\n", __func__, event);
if (event == I2C_START_SEND)
s->ready = 1;
return 0;
}
static uint8_t isl29003dl_recv(I2CSlave *i2c)
{
ISL29003DLState *s = ISL29003DL(i2c);
printf("Reading lightsensor register %d\n", s->cmd);
int res = 0;
switch(s->cmd) {
case LIGHTSENSOR_COMMAND:
res = s->command;
break;
case LIGHTSENSOR_CONTROL:
res = s->ctrl;
break;
case LIGHTSENSOR_LSB_SENSOR:
res = s->lsb_sensor;
break;
case LIGHTSENSOR_MSB_SENSOR:
res = s->msb_sensor;
break;
default:
res = 0;
printf("%s unknown register %d\n", __func__, s->cmd);
}
s->cmd += 1;
return res;
}
static int isl29003dl_send(I2CSlave *i2c, uint8_t data)
{
ISL29003DLState *s = ISL29003DL(i2c);
if (s->ready)
{
s->curreg = data;
s->ready = 0;
printf("%s Lightsensor ready\n", __func__);
}
else
{
switch(s->curreg++)
{
case LIGHTSENSOR_COMMAND:
s->command = data;
if ((s->command >> 7) == 1)
{
s->lsb_sensor = 0xE;
s->msb_sensor = 0xE << 4;
s->it_hi = 0xF;
s->it_lo = 0x0;
}
break;
default:
printf("%s unknown register %d\n", __func__, s->curreg-1);
}
}
printf("Writing lightsensor data %d\n", s->cmd);
return 0;
}
static void isl29003dl_init(Object *obj)
{
}
static void isl29003dl_class_init(ObjectClass *klass, void *data)
{
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
k->event = isl29003dl_event;
k->recv = isl29003dl_recv;
k->send = isl29003dl_send;
}
static const TypeInfo isl29003dl_info = {
.name = TYPE_ISL29003DL,
.parent = TYPE_I2C_SLAVE,
.instance_init = isl29003dl_init,
.instance_size = sizeof(ISL29003DLState),
.class_init = isl29003dl_class_init,
};
static void isl29003dl_register_types(void)
{
type_register_static(&isl29003dl_info);
}
type_init(isl29003dl_register_types)
+25 -11
View File
@@ -3,9 +3,11 @@
#include "ui/console.h"
#include "hw/display/framebuffer.h"
int lcd_brightness = 255;
static uint64_t ipod_touch_lcd_read(void *opaque, hwaddr addr, unsigned size)
{
//printf("%s: read from location 0x%08x\n", __func__, addr);
// printf("%s: read from location 0x%08x\n", __func__, addr);
IPodTouchLCDState *s = (IPodTouchLCDState *)opaque;
switch(addr)
@@ -26,8 +28,10 @@ static uint64_t ipod_touch_lcd_read(void *opaque, hwaddr addr, unsigned size)
return s->w1_display_resolution_info;
case 0x1b10:
return 2;
case 0x1b14:
return 0x3;
default:
// hw_error("%s: read invalid location 0x%08x.\n", __func__, addr);
printf("%s: read invalid location 0x%08x.\n", __func__, addr);
break;
}
return 0;
@@ -36,15 +40,16 @@ static uint64_t ipod_touch_lcd_read(void *opaque, hwaddr addr, unsigned size)
static void ipod_touch_lcd_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
{
IPodTouchLCDState *s = (IPodTouchLCDState *)opaque;
//printf("%s: writing 0x%08x to 0x%08x\n", __func__, val, addr);
// printf("%s: writing 0x%08x to 0x%08x\n", __func__, val, addr);
switch(addr) {
case 0x4:
s->lcd_con = val;
break;
case 0xC:
s->unknown1 = val;
s->render = val;
qemu_irq_lower(s->irq);
// qemu_irq_raise(s->irq);
break;
case 0x20:
s->w1_display_depth_info = val;
@@ -61,6 +66,11 @@ static void ipod_touch_lcd_write(void *opaque, hwaddr addr, uint64_t val, unsign
}
}
void lcd_changebrightness(int brightness)
{
lcd_brightness = brightness & 0xFF;
}
static void lcd_invalidate(void *opaque)
{
IPodTouchLCDState *s = opaque;
@@ -69,6 +79,7 @@ static void lcd_invalidate(void *opaque)
static void draw_line32_32(void *opaque, uint8_t *d, const uint8_t *s, int width, int deststep)
{
// IPodTouchLCDState *lcd = (IPodTouchLCDState *) opaque;
uint8_t r, g, b;
do {
@@ -77,8 +88,8 @@ static void draw_line32_32(void *opaque, uint8_t *d, const uint8_t *s, int width
b = s[0];
g = s[1];
r = s[2];
//printf("R: %d, G: %d, B: %d\n", r, g, b);
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
// printf("R: %d, G: %d, B: %d, A: %d\n", r, g, b, lcd_brightness);
((uint32_t *) d)[0] = rgb_to_pixel32(round((float)r * ((float)lcd_brightness / 255.0f)), round((float)g * ((float)lcd_brightness / 255.0f)), round((float)b * ((float)lcd_brightness / 255.0f)));
s += 4;
d += 4;
} while (-- width != 0);
@@ -86,7 +97,7 @@ static void draw_line32_32(void *opaque, uint8_t *d, const uint8_t *s, int width
static void lcd_refresh(void *opaque)
{
//fprintf(stderr, "%s: refreshing LCD screen\n", __func__);
// printf("%s: refreshing LCD screen\n", __func__);
IPodTouchLCDState *lcd = (IPodTouchLCDState *) opaque;
DisplaySurface *surface = qemu_console_surface(lcd->con);
@@ -141,7 +152,7 @@ static const GraphicHwOps gfx_ops = {
static void ipod_touch_lcd_mouse_event(void *opaque, int x, int y, int z, int buttons_state)
{
//printf("CLICKY %d %d %d %d\n", x, y, z, buttons_state);
// printf("x %d y %d z %d state %d\n", x, y, z, buttons_state);
// convert x and y to fractional numbers
float fx = x / pow(2, 15);
@@ -165,9 +176,12 @@ static void refresh_timer_tick(void *opaque)
{
IPodTouchLCDState *s = (IPodTouchLCDState *)opaque;
qemu_irq_raise(s->irq);
if (s->render == 0x1)
qemu_irq_raise(s->irq);
else if (s->render == 0xFF)
qemu_irq_lower(s->irq);
timer_mod(s->refresh_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + NANOSECONDS_PER_SECOND / LCD_REFRESH_RATE_FREQUENCY);
timer_mod(s->refresh_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + NANOSECONDS_PER_SECOND / 60);//LCD_REFRESH_RATE_FREQUENCY);
}
static void ipod_touch_lcd_realize(DeviceState *dev, Error **errp)
@@ -215,4 +229,4 @@ static void ipod_touch_machine_types(void)
type_register_static(&ipod_touch_lcd_info);
}
type_init(ipod_touch_machine_types)
type_init(ipod_touch_machine_types)
+15 -2
View File
@@ -12,8 +12,21 @@ static uint8_t lis302dl_recv(I2CSlave *i2c)
switch(s->cmd) {
case ACCEL_WHOAMI:
return ACCEL_WHOAMI_VALUE; // whoami value
return ACCEL_WHOAMI_VALUE;
case ACCEL_OUT_X:
return s->ctrl_reg1 == 1 ? s->out_x : 0;
case ACCEL_OUT_Y:
return s->ctrl_reg1 << 1 == 1 ? s->out_y : 0;
case ACCEL_OUT_Z:
return s->ctrl_reg1 << 2 == 1 ? s->out_z : 0;
case ACCEL_CTRL_REG1:
return s->ctrl_reg1;
case ACCEL_CTRL_REG2:
return s->ctrl_reg2;
case ACCEL_CTRL_REG3:
return s->ctrl_reg3;
default:
printf("%s Unknown register %d\n", __func__, s->cmd);
return 0;
}
}
@@ -52,4 +65,4 @@ static void lis302dl_register_types(void)
type_register_static(&lis302dl_info);
}
type_init(lis302dl_register_types)
type_init(lis302dl_register_types)
+21 -5
View File
@@ -9,7 +9,9 @@ static uint32_t reverse_byte_order(uint32_t value) {
static uint64_t ipod_touch_mbx1_read(void *opaque, hwaddr addr, unsigned size)
{
printf("%s: read from location 0x%08x\n", __func__, addr);
IPodTouchMBXState *s = (IPodTouchMBXState *)opaque;
if (addr != 0x1020)
printf("%s: read from location 0x%08x\n", __func__, addr);
switch(addr)
{
case 0x12c:
@@ -17,7 +19,7 @@ static uint64_t ipod_touch_mbx1_read(void *opaque, hwaddr addr, unsigned size)
case 0xf00:
return (2 << 0x10) | (1 << 0x18); // seems to be some kind of identifier
case 0x1020:
return 0x10000;
return s->addr != 0x0 ? s->addr : 0x10000;
default:
break;
}
@@ -28,10 +30,19 @@ static void ipod_touch_mbx1_write(void *opaque, hwaddr addr, uint64_t val, unsig
{
IPodTouchMBXState *s = (IPodTouchMBXState *)opaque;
fprintf(stderr, "%s: writing 0x%08x to 0x%08x\n", __func__, val, addr);
switch(addr)
{
case 0x1020:
s->addr = val;
break;
}
}
static void patch_kernel()
static void patch_kernel(bool alreadypatched)
{
if (alreadypatched) return;
alreadypatched = 1;
// patch the loading of the AppleBCM4325 driver
char *bcm4325_vars = "test";
@@ -91,11 +102,16 @@ static void patch_kernel()
static uint64_t ipod_touch_mbx2_read(void *opaque, hwaddr addr, unsigned size)
{
IPodTouchMBXState *s = (IPodTouchMBXState *)opaque;
printf("%s: read from location 0x%08x\n", __func__, addr);
switch(addr)
{
case 0xC:
patch_kernel();
patch_kernel(s->alreadypatched);
break;
case 0x4:
return 0xFF;
break;
default:
break;
}
@@ -149,4 +165,4 @@ static void ipod_touch_mbx_register_types(void)
type_register_static(&ipod_touch_mbx_type_info);
}
type_init(ipod_touch_mbx_register_types)
type_init(ipod_touch_mbx_register_types)
+8 -4
View File
@@ -2,7 +2,8 @@
static uint64_t ipod_touch_mipi_dsi_read(void *opaque, hwaddr addr, unsigned size)
{
fprintf(stderr, "%s: read from location 0x%08x\n", __func__, addr);
if (addr != 0x00000)
fprintf(stderr, "%s: read from location 0x%08lx\n", __func__, addr);
IPodTouchMIPIDSIState *s = (IPodTouchMIPIDSIState *)opaque;
switch(addr)
@@ -24,7 +25,7 @@ static uint64_t ipod_touch_mipi_dsi_read(void *opaque, hwaddr addr, unsigned siz
case REG_FIFOCTRL:
return rDSIM_FIFOCTRL_EmptyHSfr;
default:
// hw_error("%s: read invalid location 0x%08x.\n", __func__, addr);
printf("%s: read invalid location 0x%08lx.\n", __func__, addr);
break;
}
return 0;
@@ -33,13 +34,16 @@ static uint64_t ipod_touch_mipi_dsi_read(void *opaque, hwaddr addr, unsigned siz
static void ipod_touch_mipi_dsi_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
{
IPodTouchMIPIDSIState *s = (IPodTouchMIPIDSIState *)opaque;
fprintf(stderr, "%s: writing 0x%08x to 0x%08x\n", __func__, val, addr);
fprintf(stderr, "%s: writing 0x%08lx to 0x%08lx\n", __func__, val, addr);
switch(addr)
{
case REG_PKTHDR:
s->pkthdr_reg = val;
break;
case 0x00000008:
if (val == 0)
printf("turning off screen\n");
default:
break;
}
@@ -89,4 +93,4 @@ static void ipod_touch_machine_types(void)
type_register_static(&ipod_touch_mipi_dsi_info);
}
type_init(ipod_touch_machine_types)
type_init(ipod_touch_machine_types)
+3 -3
View File
@@ -199,7 +199,7 @@ static uint32_t ipod_touch_multitouch_transfer(SSIPeripheral *dev, uint32_t valu
s->out_buffer = (uint8_t *) s->next_frame;
}
else {
hw_error("Unknown command 0x%02x!", value);
printf("%s Unknown command 0x%02x!\n", __func__, value);
}
}
@@ -311,8 +311,8 @@ static MTFrame *get_frame(IPodTouchMultitouchState *s, uint8_t event, float x, f
// compute the velocity
int diff_x = (int)((x - s->prev_touch_x) * MT_INTERNAL_SENSOR_SURFACE_WIDTH);
int diff_y = (int)((x - s->prev_touch_y) * MT_INTERNAL_SENSOR_SURFACE_HEIGHT);
frame->finger_data.velX = diff_x / (elapsed_ns - s->last_frame_timestamp) * 1000;
frame->finger_data.velY = diff_y / (elapsed_ns - s->last_frame_timestamp) * 1000;
frame->finger_data.velX = diff_x / (elapsed_ns + 1 - s->last_frame_timestamp) * 1000;
frame->finger_data.velY = diff_y / (elapsed_ns + 1 - s->last_frame_timestamp) * 1000;
frame->finger_data.x = (int)(x * MT_INTERNAL_SENSOR_SURFACE_WIDTH);
frame->finger_data.y = (int)(y * MT_INTERNAL_SENSOR_SURFACE_HEIGHT);
+3 -3
View File
@@ -2,7 +2,7 @@
static void initialize_nor(IPodTouchNORSPIState *s)
{
unsigned long fsize;
gsize fsize;
if (g_file_get_contents(s->nor_path, (char **)&s->nor_data, &fsize, NULL)) {
s->nor_initialized = true;
}
@@ -67,8 +67,8 @@ static uint32_t ipod_touch_nor_spi_transfer(SSIPeripheral *dev, uint32_t value)
s->out_buf[2] = 0x02;
}
else {
printf("Unknown command %d!\n", value);
hw_error("Unknown command 0x%02x!", value);
printf("%s Unknown command 0x%02x!\n", __func__, value);
// hw_error("Unknown command 0x%02x!", value);
}
return 0x0;
+33 -4
View File
@@ -1,7 +1,21 @@
#include "hw/arm/ipod_touch_pcf50633_pmu.h"
#include "hw/arm/ipod_touch_lcd.h"
static int pcf50633_event(I2CSlave *i2c, enum i2c_event event)
{
Pcf50633State *s = PCF50633(i2c);
// printf("%s Event %d\n", __func__, s->cmd);
if (event == I2C_START_SEND)
{
// printf("%s start send %d\n", __func__, s->cmd);
}
else if (event == I2C_FINISH)
{
s->ready = 1;
// printf("%s end send %d\n", __func__, s->cmd);
}
return 0;
}
@@ -27,10 +41,10 @@ static uint8_t pcf50633_recv(I2CSlave *i2c)
switch(s->cmd) {
case PMU_MBCS1:
res = 0; // battery power source
res = 1; // battery power source
break;
case PMU_ADCC1:
res = 0; // battery charge voltage
res = 3; // battery charge voltage
break;
case PMU_RTCSC: // seconds
res = int_to_bcd(tm.tm_sec);
@@ -70,7 +84,22 @@ static uint8_t pcf50633_recv(I2CSlave *i2c)
static int pcf50633_send(I2CSlave *i2c, uint8_t data)
{
Pcf50633State *s = PCF50633(i2c);
s->cmd = data;
if (s->ready)
{
s->curreg = data;
s->ready = 0;
}
else
{
s->cmd = data;
}
printf("Writing PMU register cmd %d reg %d\n", s->cmd, s->curreg);
switch(s->curreg) {
case PMU_DSBL1:
lcd_changebrightness(s->cmd);
break;
}
return 0;
}
@@ -101,4 +130,4 @@ static void pcf50633_register_types(void)
type_register_static(&pcf50633_info);
}
type_init(pcf50633_register_types)
type_init(pcf50633_register_types)
+12 -9
View File
@@ -12,7 +12,7 @@ void sdio_exec_cmd(IPodTouchSDIOState *s)
uint32_t cmd_type = s->cmd & 0x3f;
uint32_t addr = (s->arg >> 9) & 0x1ffff;
uint32_t func = (s->arg >> 28) & 0x7;
//printf("SDIO CMD: %d, ADDR: %d, FUNC: %d\n", cmd_type, addr, func);
printf("SDIO CMD: %d, ADDR: %d, FUNC: %d\n", cmd_type, addr, func);
if(cmd_type == 0x3) {
// RCA request - ignore
}
@@ -52,7 +52,7 @@ void sdio_exec_cmd(IPodTouchSDIOState *s)
// CMD53 - block transfer
addr = addr & 0x7fff;
bool is_write = (s->arg >> 31) != 0;
printf("SDIO: Executing cmd53 with block size %d and %d blocks (reg address: 0x%08x, destination address: 0x%08x, write? %d)\n", s->blklen, s->numblk, addr, s->baddr, is_write);
printf("SDIO: Executing cmd53 func %x with block size %d and %d blocks (reg address: 0x%08x, destination address: 0x%08x, write? %d)\n", func, s->blklen, s->numblk, addr, s->baddr, is_write);
if(is_write) {
if(func == 0x1) {
@@ -61,7 +61,7 @@ void sdio_exec_cmd(IPodTouchSDIOState *s)
else if(func == 0x2) {
// this is a BCM4325 command - add a frame to the queue and schedule the IRQ request to indicate that the command has been completed
BCM4325FrameHeaderPacket *frame_header = calloc(sizeof(BCM4325FrameHeaderPacket), sizeof(uint8_t *));
uint16_t length = 14;
uint16_t length = s->blklen * s->numblk;
frame_header->frame_length = length;
frame_header->checksum = length ^ 0xffff;
g_queue_push_tail(s->rx_fifo, frame_header);
@@ -83,6 +83,9 @@ void sdio_exec_cmd(IPodTouchSDIOState *s)
if(!frame_header) {
// create an empty frame
frame_header = calloc(sizeof(BCM4325FrameHeaderPacket), sizeof(uint8_t *));
frame_header->frame_length = s->blklen * s->numblk;
frame_header->checksum = (s->blklen * s->numblk) ^ 0xffff;
}
cpu_physical_memory_write(s->baddr, frame_header, sizeof(BCM4325FrameHeaderPacket));
}
@@ -101,7 +104,7 @@ void sdio_exec_cmd(IPodTouchSDIOState *s)
static void ipod_touch_sdio_write(void *opaque, hwaddr addr, uint64_t value, unsigned size)
{
//printf("%s: writing 0x%08x to 0x%08x\n", __func__, value, addr);
printf("%s: writing 0x%08x to 0x%08x\n", __func__, value, addr);
IPodTouchSDIOState *s = (struct IPodTouchSDIOState *) opaque;
@@ -146,7 +149,7 @@ static void ipod_touch_sdio_write(void *opaque, hwaddr addr, uint64_t value, uns
static uint64_t ipod_touch_sdio_read(void *opaque, hwaddr addr, unsigned size)
{
//printf("%s: offset = 0x%08x\n", __func__, addr);
printf("%s: offset = 0x%08x\n", __func__, addr);
IPodTouchSDIOState *s = (struct IPodTouchSDIOState *) opaque;
@@ -164,11 +167,11 @@ static uint64_t ipod_touch_sdio_read(void *opaque, hwaddr addr, unsigned size)
case SDIO_RESP0:
return s->resp0;
case SDIO_RESP1:
return s->resp1;
return s->resp1 == 0 ? 0x7465 : s->resp1;
case SDIO_RESP2:
return s->resp2;
return s->resp2 == 0 ? 0x7374 : s->resp2;
case SDIO_RESP3:
return s->resp3;
return s->resp3 == 0 ? 0xFFFF : s->resp3;
case SDIO_CSR:
return s->csr;
case SDIO_IRQ:
@@ -249,4 +252,4 @@ static void ipod_touch_sdio_register_types(void)
type_register_static(&ipod_touch_sdio_type_info);
}
type_init(ipod_touch_sdio_register_types)
type_init(ipod_touch_sdio_register_types)
+2 -3
View File
@@ -1,7 +1,6 @@
#include "hw/arm/ipod_touch_sha1.h"
static uint64_t swapLong(void *X) {
uint64_t x = (uint64_t) X;
static uint64_t swapLong(uint64_t x) {
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
@@ -150,4 +149,4 @@ static void ipod_touch_machine_types(void)
type_register_static(&ipod_touch_sha1_info);
}
type_init(ipod_touch_machine_types)
type_init(ipod_touch_machine_types)
+2 -2
View File
@@ -93,7 +93,7 @@ static uint64_t s5l8900_timer1_read(void *opaque, hwaddr addr, unsigned size)
case TIMER_TICKSLOW:
return s->ticks_low;
case TIMER_IRQSTAT:
return ~0; // s->irqstat;
return s->irqstat; // ~0; // s->irqstat;
case TIMER_IRQLATCH:
return 0xffffffff;
@@ -140,4 +140,4 @@ static void ipod_touch_machine_types(void)
type_register_static(&ipod_touch_timer_info);
}
type_init(ipod_touch_machine_types)
type_init(ipod_touch_machine_types)
+2 -2
View File
@@ -2,7 +2,7 @@
static uint64_t ipod_touch_unknown1_read(void *opaque, hwaddr addr, unsigned size)
{
//fprintf(stderr, "%s: offset = 0x%08x\n", __func__, addr);
fprintf(stderr, "%s: offset = 0x%08x\n", __func__, addr);
switch (addr) {
case 0x140:
@@ -53,4 +53,4 @@ static void ipod_touch_unknown1_register_types(void)
type_register_static(&ipod_touch_unknown1_type_info);
}
type_init(ipod_touch_unknown1_register_types)
type_init(ipod_touch_unknown1_register_types)
+176 -15
View File
@@ -95,7 +95,7 @@ static void synopsys_usb_update_in_ep(synopsys_usb_state *_state, uint8_t _ep)
synopsys_usb_update_ep(_state, eps);
if(eps->control & USB_EPCON_ENABLE)
;//printf("USB: IN transfer queued on %d.\n", _ep);
;printf("USB: IN transfer queued on %d.\n", _ep);
}
static void synopsys_usb_update_out_ep(synopsys_usb_state *_state, uint8_t _ep)
@@ -107,6 +107,157 @@ static void synopsys_usb_update_out_ep(synopsys_usb_state *_state, uint8_t _ep)
;//printf("USB: OUT transfer queued on %d.\n", _ep);
}
static int synopsys_usb_tcp_callback(tcp_usb_state_t *_state, void *_arg, tcp_usb_header_t *_hdr, char *_buffer)
{
synopsys_usb_state *state = _arg;
_hdr->addr = (state->dcfg & DCFG_DEVICEADDRMSK) >> DCFG_DEVICEADDR_SHIFT;
if(_hdr->flags & tcp_usb_reset)
{
state->gintsts |= GINTMSK_RESET;
synopsys_usb_update_irq(state);
return 0;
}
if(_hdr->flags & tcp_usb_enumdone)
{
state->gintsts |= GINTMSK_ENUMDONE;
}
int ret;
uint8_t ep = _hdr->ep & 0x7f;
if(_hdr->ep & USB_DIR_IN)
{
synopsys_usb_ep_state *eps = &state->in_eps[ep];
if(eps->control & USB_EPCON_STALL)
{
eps->control &=~ USB_EPCON_STALL; // Should this be EP0 only
//printf("USB: Stall.\n");
ret = USB_RET_STALL;
}
else if(eps->control & USB_EPCON_ENABLE)
{
// Do IN transfer!
eps->control &=~ USB_EPCON_ENABLE;
size_t sz = eps->tx_size & DEPTSIZ_XFERSIZ_MASK;
size_t amtDone = sz;
if(amtDone > _hdr->length)
amtDone = _hdr->length;
if(eps->fifo >= USB_NUM_FIFOS)
hw_error("usb_synopsys: USB transfer on non-existant FIFO %d!\n", eps->fifo);
size_t txfz = synopsys_usb_tx_fifo_size(state, eps->fifo);
if(amtDone > txfz)
amtDone = txfz;
size_t txfs = synopsys_usb_tx_fifo_start(state, eps->fifo);
if(txfs + txfz > sizeof(state->fifos))
hw_error("usb_synopsys: USB transfer would overflow FIFO buffer!\n");
printf("USB: Starting IN transfer on EP %d (%d bytes)...\n", ep, amtDone);
if(amtDone > 0)
{
if(eps->dma_address)
{
cpu_physical_memory_read(eps->dma_address, &state->fifos[txfs], amtDone);
eps->dma_address += amtDone;
}
memcpy(_buffer, (char*)&state->fifos[txfs], amtDone);
}
printf("USB: IN transfer complete!\n");
eps->tx_size = (eps->tx_size &~ DEPTSIZ_XFERSIZ_MASK)
| ((sz-amtDone) & DEPTSIZ_XFERSIZ_MASK);
eps->interrupt_status |= USB_EPINT_XferCompl;
ret = amtDone;
}
else
ret = USB_RET_NAK;
}
else // OUT
{
synopsys_usb_ep_state *eps = &state->out_eps[ep];
printf("EPS control: %d\n", eps->control);
if(eps->control & USB_EPCON_STALL)
{
eps->control &=~ USB_EPCON_STALL; // Should this be EP0 only
//printf("USB: Stall.\n");
ret = USB_RET_STALL;
}
else if(eps->control & USB_EPCON_ENABLE)
{
// Do OUT transfer!
eps->control &=~ USB_EPCON_ENABLE;
size_t sz = eps->tx_size & DEPTSIZ_XFERSIZ_MASK;
size_t amtDone = sz;
if(amtDone > _hdr->length)
amtDone = _hdr->length;
size_t rxfz = state->grxfsiz;
if(amtDone > rxfz)
amtDone = rxfz;
if(rxfz > sizeof(state->fifos))
hw_error("usb_synopsys: USB transfer would overflow FIFO buffer!\n");
printf("USB: Starting OUT transfer on EP %d (%d)...\n", ep, amtDone);
if(amtDone > 0)
{
memcpy((char*)state->fifos, _buffer, amtDone);
if(eps->dma_address)
{
printf("USB: DMA copying to 0x%08x.\n", eps->dma_address);
cpu_physical_memory_write(eps->dma_address, state->fifos, amtDone);
eps->dma_address += amtDone;
}
}
printf("USB: OUT transfer complete!\n");
if(_hdr->flags & tcp_usb_setup)
{
/*
printf("USB: Setup %02x %02x %02x %02x %02x %02x %02x %02x\n",
state->fifos[0],
state->fifos[1],
state->fifos[2],
state->fifos[3],
state->fifos[4],
state->fifos[5],
state->fifos[6],
state->fifos[7]);
*/
eps->interrupt_status |= USB_EPINT_SetUp;
}
else
eps->interrupt_status |= USB_EPINT_XferCompl;
eps->tx_size = (eps->tx_size &~ DEPTSIZ_XFERSIZ_MASK)
| ((sz-amtDone) & DEPTSIZ_XFERSIZ_MASK);
ret = amtDone;
}
else
ret = USB_RET_NAK;
}
synopsys_usb_update_irq(state);
return ret;
}
static uint32_t synopsys_usb_in_ep_read(synopsys_usb_state *_state, uint8_t _ep, hwaddr _addr)
{
if(_ep >= USB_NUM_ENDPOINTS)
@@ -283,6 +434,10 @@ static void synopsys_usb_in_ep_write(synopsys_usb_state *_state, int _ep, hwaddr
return;
}
if (_addr == 0x10) {
printf("USB: Setting TX size of EP %d to %d.\n", _ep, _val);
}
switch (_addr)
{
case 0x00:
@@ -355,7 +510,7 @@ static void synopsys_usb_write(void *opaque, hwaddr _addr, uint64_t _val, unsign
{
synopsys_usb_state *state = (synopsys_usb_state *)opaque;
//printf("USB: Write 0x%08x to 0x%08x.\n", _val, _addr);
printf("USB: Write 0x%08x to 0x%08x.\n", _val, _addr);
switch(_addr)
{
@@ -379,20 +534,22 @@ static void synopsys_usb_write(void *opaque, hwaddr _addr, uint64_t _val, unsign
state->grstctl = GRSTCTL_CORESOFTRESET;
// Do reset stuff
// if(state->server_host)
// {
// tcp_usb_cleanup(&state->tcp_state);
// tcp_usb_init(&state->tcp_state, synopsys_usb_tcp_callback, NULL, state);
if(state->server_host)
{
tcp_usb_cleanup(&state->tcp_state);
tcp_usb_init(&state->tcp_state, synopsys_usb_tcp_callback, NULL, state);
// printf("Connecting to USB server at %s:%d...\n",
// state->server_host, state->server_port);
printf("Connecting to USB server at %s:%d...\n",
state->server_host, state->server_port);
// int ret = tcp_usb_connect(&state->tcp_state, state->server_host, state->server_port);
// if(ret < 0)
// hw_error("Failed to connect to USB server (%d).\n", ret);
// printf("Connected to USB server.\n");
// }
int ret = tcp_usb_connect(&state->tcp_state, state->server_host, state->server_port);
if(ret < 0) {
printf("Failed to connect to USB server (%d).\n", ret);
}
else {
printf("Connected to USB server.\n");
}
}
state->grstctl &= ~GRSTCTL_CORESOFTRESET;
state->grstctl |= GRSTCTL_AHBIDLE;
@@ -517,6 +674,7 @@ static void s5l8900_usb_otg_reset(DeviceState *d)
state->ghwcfg4);
state->pcgcctl = 3;
state->grstctl = GRSTCTL_AHBIDLE;
state->gahbcfg = 0;
state->gusbcfg = 0;
@@ -540,6 +698,9 @@ static void s5l8900_usb_otg_reset(DeviceState *d)
state->grxfsiz = 0x100;
state->gnptxfsiz = (0x100 << 16) | 0x100;
state->server_host = "localhost";
state->server_port = 1235;
uint32_t counter = 0x200;
int i;
for(i = 0; i < USB_NUM_FIFOS; i++)
@@ -613,4 +774,4 @@ static void s5l8900_usb_otg_register_types(void)
type_register_static(&s5l8900_usb_otg_info);
}
type_init(s5l8900_usb_otg_register_types)
type_init(s5l8900_usb_otg_register_types)
+7 -4
View File
@@ -16,9 +16,12 @@ static uint64_t ipod_touch_usb_phys_read(void *opaque, hwaddr addr, unsigned siz
return s->usb_unknown1;
case REG_OPHYTUNE:
return s->usb_ophytune;
case REG_CABLE:
return s->is_cable_connected;
default:
return 0x0;
//hw_error("%s: read invalid location 0x%08x\n", __func__, addr);
//return 0x0;
printf("%s: read invalid location 0x%08x\n", __func__, addr);
return 0x0;
}
}
@@ -45,7 +48,7 @@ static void ipod_touch_usb_phys_write(void *opaque, hwaddr addr, uint64_t val, u
return;
default:
//hw_error("%s: write invalid location 0x%08x.\n", __func__, addr);
printf("%s: write invalid location 0x%08x.\n", __func__, addr);
return;
}
}
@@ -83,4 +86,4 @@ static void ipod_touch_usb_phys_register_types(void)
type_register_static(&ipod_touch_usb_phys_type_info);
}
type_init(ipod_touch_usb_phys_register_types)
type_init(ipod_touch_usb_phys_register_types)
+1 -1
View File
@@ -65,7 +65,7 @@ arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
arm_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c'))
arm_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
arm_ss.add(when: 'CONFIG_XEN', if_true: files('xen_arm.c'))
arm_ss.add(when: 'CONFIG_IPOD_TOUCH_2G', if_true: files('ipod_touch_2g.c', 'ipod_touch_clock.c', 'ipod_touch_chipid.c', 'ipod_touch_gpio.c', 'ipod_touch_sysic.c', 'ipod_touch_timer.c', 'ipod_touch_usb_otg.c', 'ipod_touch_usb_phys.c', 'ipod_touch_spi.c', 'ipod_touch_nor_spi.c', 'ipod_touch_sha1.c', 'ipod_touch_aes.c', 'ipod_touch_pke.c', 'ipod_touch_pcf50633_pmu.c', 'ipod_touch_unknown1.c', 'ipod_touch_lcd.c', 'ipod_touch_mipi_dsi.c', 'ipod_touch_fmss.c', 'ipod_touch_mbx.c', 'ipod_touch_cd3272_mikey.c', 'ipod_touch_lis302dl.c', 'ipod_touch_multitouch.c', 'ipod_touch_scaler_csc.c', 'ipod_touch_sdio.c', 'ipod_touch_tvout.c'))
arm_ss.add(when: 'CONFIG_IPOD_TOUCH_2G', if_true: files('ipod_touch_2g.c', 'ipod_touch_clock.c', 'ipod_touch_chipid.c', 'ipod_touch_gpio.c', 'ipod_touch_sysic.c', 'ipod_touch_timer.c', 'ipod_touch_usb_otg.c', 'ipod_touch_usb_phys.c', 'ipod_touch_spi.c', 'ipod_touch_nor_spi.c', 'ipod_touch_sha1.c', 'ipod_touch_aes.c', 'ipod_touch_pke.c', 'ipod_touch_pcf50633_pmu.c', 'ipod_touch_unknown1.c', 'ipod_touch_lcd.c', 'ipod_touch_mipi_dsi.c', 'ipod_touch_fmss.c', 'ipod_touch_mbx.c', 'ipod_touch_cd3272_mikey.c', 'ipod_touch_lis302dl.c', 'ipod_touch_multitouch.c', 'ipod_touch_scaler_csc.c', 'ipod_touch_sdio.c', 'ipod_touch_tvout.c', 'ipod_touch_isl29003dl.c'))
system_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c'))
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4_boards.c'))
+2
View File
@@ -11,6 +11,8 @@ system_ss.add(when: 'CONFIG_USB', if_true: files(
'pcap.c',
))
system_ss.add(when: 'CONFIG_USB', if_true: files('tcp_usb.c'))
# usb host adapters
system_ss.add(when: 'CONFIG_USB_UHCI', if_true: files('hcd-uhci.c'))
system_ss.add(when: 'CONFIG_USB_OHCI', if_true: files('hcd-ohci.c'))
+524
View File
@@ -0,0 +1,524 @@
/*
* USB over TCP driver.
*
* Copyright (c) 2011 Richard Ian Taylor.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "hw/usb/tcp_usb.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define DEBUG_TCP_USB
void tcp_usb_init(tcp_usb_state_t *_state, tcp_usb_callback_t _cb, tcp_usb_closed_t _closed, void *_arg)
{
_state->data_callback = _cb;
_state->closed_callback = _closed;
_state->callback_arg = _arg;
_state->socket = -1;
_state->closed = 1;
_state->state = tcp_usb_idle;
_state->amount_done = 0;
}
void tcp_usb_cleanup(tcp_usb_state_t *_state)
{
if(_state->socket >= 0)
{
close(_state->socket);
qemu_set_fd_handler(_state->socket, NULL, NULL, NULL);
_state->socket = -1;
}
}
int tcp_usb_closed(tcp_usb_state_t *_state)
{
return _state->closed != 0;
}
static void tcp_usb_do_closed(tcp_usb_state_t *_state)
{
if(_state->closed)
return;
_state->closed = 1;
qemu_set_fd_handler(_state->socket, NULL, NULL, NULL);
if(_state->closed_callback)
_state->closed_callback(_state, _state->callback_arg);
}
#ifdef DEBUG_TCP_USB
static void hexdump(const void *_data, size_t _amt)
{
char *ptr = (char*)_data;
int i;
for(i = 0; i < _amt; i++)
{
if((i%8) == 0)
fprintf(stderr, "\t");
fprintf(stderr, "%02x ", (ptr[i] & 0xFF));
if((i%8) == 7)
fprintf(stderr, "\n");
}
if((i%8) != 0)
fprintf(stderr, "\n");
}
# define debug_hexdump(title, data, amt); fprintf(stderr, title); hexdump((data), (amt));
# define debug_printf(args...) printf(args);
#else
# define debug_hexdump(a, b, c)
# define debug_printf(a...)
#endif // DEBUG_TCP_USB
static void tcp_usb_callback(tcp_usb_state_t *state, int _can_read, int _can_write)
{
if(state->closed)
return;
int ret;
switch(state->state)
{
case tcp_usb_idle:
if(!_can_read)
return;
debug_printf("%s: tcp_usb_idle.\n", __func__);
// Receiving new request
state->header = malloc(sizeof(*state->header));
state->amount_done = 0;
state->state = tcp_usb_read_request;
// Fall through
case tcp_usb_read_request:
debug_printf("%s: tcp_usb_read_request\n", __func__);
if(state->amount_done < sizeof(*state->header))
{
ret = read(state->socket,
((char*)state->header) + state->amount_done,
sizeof(*state->header) - state->amount_done);
if(ret == 0 && _can_read)
{
free(state->header);
tcp_usb_do_closed(state);
return;
}
else if(ret == EWOULDBLOCK || ret == 0 || ret == -1)
return;
else if(ret < 0)
{
fprintf(stderr, "tcp_usb: Error %d reading request header!\n", ret);
return;
}
_can_read = 0;
state->amount_done += ret;
if(state->amount_done < sizeof(*state->header))
return;
debug_hexdump("tcp_usb: Got Header: ", state->header, sizeof(*state->header));
debug_printf("Length: %d\n", state->header->length);
if(state->header->length > 0)
state->buffer = malloc(state->header->length);
else
state->buffer = NULL;
}
if((state->header->ep & USB_DIR_IN) == 0 && state->header->length > 0) // OUT
{
ret = read(state->socket,
((char*)state->buffer) + (state->amount_done - sizeof(*state->header)),
state->header->length - (state->amount_done - sizeof(*state->header)));
printf("RET: %d\n", ret);
if(ret == 0 && _can_read)
{
free(state->header);
if(state->buffer)
free(state->buffer);
tcp_usb_do_closed(state);
return;
}
else if(ret == EWOULDBLOCK || ret == 0 || ret == -1)
return;
else if(ret < 0)
{
printf("tcp_usb: Error %d reading request data!\n", ret);
return;
}
_can_read = 0;
state->amount_done += ret;
if(state->amount_done < sizeof(*state->header) + state->header->length)
return;
debug_hexdump("tcp_usb: Read: ", state->buffer, state->header->length);
}
// Transfer complete! Call callback!
if(state->data_callback)
{
state->state = tcp_usb_write_response;
state->amount_done = 0;
debug_printf("tcp_usb: Calling callback.\n");
ret = state->data_callback(state, state->callback_arg, state->header, state->buffer);
state->header->length = ret;
}
else
{
fprintf(stderr, "tcp_usb: Packet received but no callback!\n");
state->state = tcp_usb_idle;
return;
}
// Fall through
case tcp_usb_write_response:
debug_printf("%s: tcp_usb_write_response\n", __func__);
if(state->amount_done < sizeof(*state->header))
{
ret = write(state->socket,
((char*)state->header) + state->amount_done,
sizeof(*state->header) - state->amount_done);
if(ret == 0 && _can_write)
{
free(state->header);
if(state->buffer)
free(state->buffer);
tcp_usb_do_closed(state);
return;
}
else if(ret == EWOULDBLOCK || ret == 0 || ret == -1)
return;
else if(ret < 0)
{
fprintf(stderr, "tcp_usb: Error %d writing response header.\n", ret);
return;
}
_can_write = 0;
state->amount_done += ret;
if(state->amount_done < sizeof(*state->header))
return;
debug_hexdump("tcp_usb: Sent Header (write response): ", state->header, sizeof(*state->header));
}
if((state->header->ep & USB_DIR_IN) != 0 && state->header->length > 0) // IN
{
ret = write(state->socket,
((char*)state->buffer) + (state->amount_done - sizeof(*state->header)),
state->header->length - (state->amount_done - sizeof(*state->header)));
if(ret == 0 && _can_write)
{
free(state->header);
if(state->buffer)
free(state->buffer);
tcp_usb_do_closed(state);
return;
}
else if(ret == EWOULDBLOCK || ret == 0 || ret == -1)
return;
else if(ret < 0)
{
fprintf(stderr, "tcp_usb: Error %d writing response data.\n", ret);
return;
}
_can_write = 0;
state->amount_done += ret;
if(state->amount_done < sizeof(*state->header) + state->header->length)
return;
debug_hexdump("tcp_usb: Wrote: ", state->buffer, state->header->length);
}
free(state->header);
if(state->buffer)
free(state->buffer);
state->state = tcp_usb_idle;
break;
case tcp_usb_write_request:
debug_printf("%s: tcp_usb_write_request\n", __func__);
if(state->amount_done < sizeof(*state->header))
{
ret = write(state->socket,
((char*)state->header) + state->amount_done,
sizeof(*state->header) - state->amount_done);
if(ret == 0 && _can_write)
{
tcp_usb_do_closed(state);
return;
}
else if(ret == EWOULDBLOCK || ret == 0 || ret == -1)
return;
else if(ret < 0)
{
fprintf(stderr, "tcp_usb: Error %d writing request header!\n", ret);
return;
}
_can_write = 0;
state->amount_done += ret;
if(state->amount_done < sizeof(*state->header))
return;
debug_hexdump("tcp_usb: Sent Header (write request): ", state->header, sizeof(*state->header));
}
if((state->header->ep & USB_DIR_IN) == 0 && state->header->length > 0) // OUT
{
ret = write(state->socket,
((char*)state->buffer) + (state->amount_done - sizeof(*state->header)),
state->header->length - (state->amount_done - sizeof(*state->header)));
if(ret == 0 && _can_write)
{
tcp_usb_do_closed(state);
return;
}
else if(ret == EWOULDBLOCK || ret == 0 || ret == -1)
return;
else if(ret < 0)
{
fprintf(stderr, "tcp_usb: Error %d writing request data!\n", ret);
return;
}
_can_write = 0;
state->amount_done += ret;
if(state->amount_done < sizeof(*state->header) + state->header->length)
return;
debug_hexdump("tcp_usb: Wrote: ", state->buffer, state->header->length);
}
state->state = tcp_usb_read_response;
state->amount_done = 0;
// Fall through
case tcp_usb_read_response:
debug_printf("%s: tcp_usb_read_response\n", __func__);
if(state->amount_done < sizeof(*state->header))
{
ret = read(state->socket,
((char*)state->header) + state->amount_done,
sizeof(*state->header) - state->amount_done);
if(ret == 0 && _can_read)
{
tcp_usb_do_closed(state);
return;
}
else if(ret == EWOULDBLOCK || ret == 0 || ret == -1)
return;
else if(ret < 0)
{
fprintf(stderr, "tcp_usb: Error %d reading response header.\n", ret);
return;
}
_can_read = 0;
state->amount_done += ret;
if(state->amount_done < sizeof(*state->header))
return;
debug_hexdump("tcp_usb: Got Header: ", state->header, sizeof(*state->header));
}
if((state->header->ep & USB_DIR_IN) != 0 && state->header->length > 0) // IN
{
ret = read(state->socket,
((char*)state->buffer) + (state->amount_done - sizeof(*state->header)),
state->header->length - (state->amount_done - sizeof(*state->header)));
if(ret == 0 && _can_read)
{
tcp_usb_do_closed(state);
return;
}
else if(ret == EWOULDBLOCK || ret == 0 || ret == -1)
return;
else if(ret < 0)
{
fprintf(stderr, "tcp_usb: Error %d reading response data.\n", ret);
return;
}
_can_read = 0;
state->amount_done += ret;
if(state->amount_done < sizeof(*state->header) + state->header->length)
return;
debug_hexdump("tcp_usb: Read: ", state->buffer, state->header->length);
}
state->state = tcp_usb_idle;
// Transfer complete! Call callback!
if(state->data_callback)
{
debug_printf("tcp_usb: calling callback!\n");
state->data_callback(state, state->callback_arg, state->header, state->buffer);
return;
}
else
{
fprintf(stderr, "tcp_usb: Request sent but no callback!\n");
state->state = tcp_usb_idle;
return;
}
break;
}
}
static void tcp_usb_read_callback(void *_arg)
{
tcp_usb_state_t *state = _arg;
tcp_usb_callback(state, 1, 0);
}
static void tcp_usb_write_callback(void *_arg)
{
tcp_usb_state_t *state = _arg;
tcp_usb_callback(state, 0, 1);
}
int tcp_usb_connect(tcp_usb_state_t *_state, char *_host, uint32_t _port)
{
_state->socket = socket(AF_INET, SOCK_STREAM, 0);
struct hostent *hostname = gethostbyname(_host);
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(_port);
memcpy(&server_addr.sin_addr.s_addr,
hostname->h_addr, hostname->h_length);
int ret = connect(_state->socket, &server_addr, sizeof(server_addr));
if(ret < 0)
return -EIO;
_state->closed = 0;
int flags = fcntl(_state->socket, F_GETFL, 0);
fcntl(_state->socket, F_SETFL, flags | O_NONBLOCK);
qemu_set_fd_handler(_state->socket, tcp_usb_read_callback, tcp_usb_write_callback, _state);
return 0;
}
int tcp_usb_request(tcp_usb_state_t *_state, tcp_usb_header_t *_header, const char *_data)
{
debug_printf("%s.\n", __func__);
if(_state->state != tcp_usb_idle)
return -EBUSY;
debug_printf("%s starting request.\n", __func__);
_state->state = tcp_usb_write_request;
_state->amount_done = 0;
_state->buffer = (char*)_data;
_state->header = _header;
tcp_usb_callback(_state, 0, 1);
return 0;
}
void tcp_usb_host_init(tcp_usb_host_state_t *_state)
{
_state->socket = -1;
}
void tcp_usb_host_cleanup(tcp_usb_host_state_t *_state)
{
if(_state->socket >= 0)
{
close(_state->socket);
_state->socket = -1;
}
}
int tcp_usb_host_okay(tcp_usb_host_state_t *_state)
{
return 0;
}
int tcp_usb_host(tcp_usb_host_state_t *_state, uint32_t _port)
{
_state->socket = socket(AF_INET, SOCK_STREAM, 0);
if(_state->socket < 0)
return -EIO;
struct linger linger;
linger.l_onoff = 0;
linger.l_linger = 0;
setsockopt(_state->socket, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger));
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(_port);
server_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(_state->socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
return -EIO;
listen(_state->socket, 5);
return 0;
}
int tcp_usb_accept(tcp_usb_host_state_t *_host, tcp_usb_state_t *_client)
{
struct sockaddr_in addr;
size_t addr_sz = sizeof(addr);
debug_printf("%s: waiting on accept...\n", __func__);
_client->socket = accept(_host->socket, &addr, &addr_sz);
if(_client->socket < 0)
{
fprintf(stderr, "%s: accept error %d.\n", __func__, errno);
return -EIO;
}
_client->closed = 0;
int flags = fcntl(_client->socket, F_GETFL, 0);
fcntl(_client->socket, F_SETFL, flags | O_NONBLOCK);
qemu_set_fd_handler(_client->socket, tcp_usb_read_callback, tcp_usb_write_callback, _client);
debug_printf("%s: USB device accepted!\n", __func__);
return 0;
}
+20 -1
View File
@@ -57,6 +57,25 @@
#define S5L8900_GPIO_G3_IRQ 0x03
#define S5L8900_GPIO_G4_IRQ 0x02
// key codes
#define KEY_UP (1 << 7)
#define KEY_P 25
#define KEY_P_DOWN KEY_P
#define KEY_P_UP (KEY_P_DOWN | KEY_UP)
#define KEY_H 35
#define KEY_H_DOWN KEY_H
#define KEY_H_UP (KEY_H_DOWN | KEY_UP)
#define KEY_MIN 12
#define KEY_MIN_DOWN KEY_MIN
#define KEY_MIN_UP (KEY_MIN_DOWN | KEY_UP)
#define KEY_PLUS 13
#define KEY_PLUS_DOWN KEY_PLUS
#define KEY_PLUS_UP (KEY_PLUS_DOWN | KEY_UP)
const int S5L8900_GPIO_IRQS[5] = { S5L8900_GPIO_G0_IRQ, S5L8900_GPIO_G1_IRQ, S5L8900_GPIO_G2_IRQ, S5L8900_GPIO_G3_IRQ, S5L8900_GPIO_G4_IRQ };
#define IT2G_CPREG_VAR_NAME(name) cpreg_##name
@@ -157,4 +176,4 @@ typedef struct {
IT2G_CPREG_VAR_DEF(REG1);
} IPodTouchMachineState;
#endif
#endif
+19
View File
@@ -0,0 +1,19 @@
#ifndef HW_CS42L58_H
#define HW_CS42L58_H
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "hw/sysbus.h"
#include "hw/i2c/i2c.h"
#include "hw/irq.h"
#define TYPE_CS42L58 "cs42l58"
OBJECT_DECLARE_SIMPLE_TYPE(CS42L58State, CS42L58)
typedef struct CS42L58State {
I2CSlave i2c;
uint32_t cmd;
} CS42L58State;
#endif
+20 -5
View File
@@ -10,19 +10,34 @@
#define TYPE_IPOD_TOUCH_GPIO "ipodtouch.gpio"
OBJECT_DECLARE_SIMPLE_TYPE(IPodTouchGPIOState, IPOD_TOUCH_GPIO)
#define GPIO_BUTTON_POWER 0xC02
#define GPIO_BUTTON_HOME 0xC01
#define GPIO_BUTTON_POWER 0xC02
#define GPIO_BUTTON_HOME 0xC01
#define GPIO_BUTTON_VOLUP 0x902
#define GPIO_BUTTON_VOLDOWN 0xC00
#define GPIO_FORCE_DFU 0xB03
#define GPIO_BUTTON_POWER_IRQ 0x7A
#define GPIO_BUTTON_HOME_IRQ 0x79
#define GPIO_BUTTON_POWER_IRQ 0x7A
#define GPIO_BUTTON_HOME_IRQ 0x79
#define GPIO_BUTTON_VOLUP_IRQ 0x78
#define GPIO_BUTTON_VOLDOWN_IRQ 0x62
#define NUM_GPIO_PADS 0xC
#define NUM_GPIO_PINS 0x20
#define GPIO2PIN(gpio) ((gpio) & 7)
#define GPIO2PAD(gpio) (((gpio) >> 8) & 0xFF)
#define GPIOADDR2PAD(addr) (addr - 0x4) / 0x20
typedef struct IPodTouchGPIOState
{
SysBusDevice parent_obj;
MemoryRegion iomem;
uint32_t gpio_state;
uint32_t gpio_state[NUM_GPIO_PADS];
} IPodTouchGPIOState;
bool gpio_is_on(uint32_t *state, uint32_t gpio);
bool gpio_is_off(uint32_t *state, uint32_t gpio);
void gpio_set_on(uint32_t *state, uint32_t gpio);
void gpio_set_off(uint32_t *state, uint32_t gpio);
#endif
+39
View File
@@ -0,0 +1,39 @@
#ifndef HW_ISL29003DL_H
#define HW_ISL29003DL_H
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "hw/sysbus.h"
#include "hw/i2c/i2c.h"
#include "hw/irq.h"
#include "time.h"
#define TYPE_ISL29003DL "isl29003dl"
OBJECT_DECLARE_SIMPLE_TYPE(ISL29003DLState, ISL29003DL)
#define LIGHTSENSOR_COMMAND 0x00
#define LIGHTSENSOR_CONTROL 0x01
#define LIGHTSENSOR_IT_HI 0x02
#define LIGHTSENSOR_IT_LO 0x03
#define LIGHTSENSOR_LSB_SENSOR 0x04
#define LIGHTSENSOR_MSB_SENSOR 0x05
#define LIGHTSENSOR_LSB_TIMER 0x06
#define LIGHTSENSOR_MSB_TIMER 0x07
typedef struct ISL29003DLState {
I2CSlave i2c;
uint32_t cmd;
uint32_t command;
uint32_t ctrl;
uint32_t curreg;
uint32_t ready;
uint32_t it_hi;
uint32_t it_lo;
uint32_t lsb_sensor;
uint32_t msb_sensor;
uint32_t lsb_timer;
uint32_t msb_timer;
} ISL29003DLState;
#endif
+5 -2
View File
@@ -22,6 +22,7 @@ typedef struct IPodTouchLCDState
QemuConsole *con;
IPodTouchMultitouchState *mt;
int invalidate;
uint8_t brightness;
MemoryRegionSection fbsection;
qemu_irq irq;
uint32_t lcd_con;
@@ -31,9 +32,11 @@ typedef struct IPodTouchLCDState
uint32_t w1_hspan;
uint32_t w1_display_depth_info;
uint32_t unknown1;
uint32_t render;
QEMUTimer *refresh_timer;
} IPodTouchLCDState;
#endif
void lcd_changebrightness(int brightness);
#endif
+13 -1
View File
@@ -12,12 +12,24 @@
OBJECT_DECLARE_SIMPLE_TYPE(LIS302DLState, LIS302DL)
#define ACCEL_WHOAMI 0x0F
#define ACCEL_OUT_X 0x29
#define ACCEL_OUT_Y 0x2B
#define ACCEL_OUT_Z 0x2D
#define ACCEL_CTRL_REG1 0x20
#define ACCEL_CTRL_REG2 0x21
#define ACCEL_CTRL_REG3 0x22
#define ACCEL_WHOAMI_VALUE 0x3B
typedef struct LIS302DLState {
I2CSlave i2c;
uint32_t cmd;
uint32_t out_x;
uint32_t out_y;
uint32_t out_z;
uint16_t ctrl_reg1;
uint16_t ctrl_reg2;
uint16_t ctrl_reg3;
} LIS302DLState;
#endif
#endif
+3 -1
View File
@@ -12,6 +12,8 @@ typedef struct IPodTouchMBXState {
SysBusDevice busdev;
MemoryRegion iomem1;
MemoryRegion iomem2;
uint64_t addr;
bool alreadypatched;
} IPodTouchMBXState;
#endif
#endif
+4 -1
View File
@@ -12,6 +12,7 @@
#define TYPE_PCF50633 "pcf50633"
OBJECT_DECLARE_SIMPLE_TYPE(Pcf50633State, PCF50633)
#define PMU_DSBL1 0x30
#define PMU_MBCS1 0x4B
#define PMU_ADCC1 0x57
@@ -27,6 +28,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(Pcf50633State, PCF50633)
typedef struct Pcf50633State {
I2CSlave i2c;
uint32_t cmd;
uint32_t ready;
uint32_t curreg;
} Pcf50633State;
#endif
#endif
+2 -1
View File
@@ -3,6 +3,7 @@
#include "hw/irq.h"
#include "hw/usb.h"
#include "hw/usb/tcp_usb.h"
#define DEVICE_NAME "usb_synopsys"
@@ -223,7 +224,7 @@ typedef struct synopsys_usb_state
char *server_host;
uint32_t server_port;
//tcp_usb_state_t tcp_state;
tcp_usb_state_t tcp_state;
uint32_t pcgcctl;
+5 -3
View File
@@ -8,11 +8,12 @@
#define TYPE_IPOD_TOUCH_USB_PHYS "ipodtouch.usbphys"
OBJECT_DECLARE_SIMPLE_TYPE(IPodTouchUSBPhysState, IPOD_TOUCH_USB_PHYS)
#define REG_OPHYPWR 0x0
#define REG_OPHYCLK 0x4
#define REG_ORSTCON 0x8
#define REG_OPHYPWR 0x0
#define REG_OPHYCLK 0x4
#define REG_ORSTCON 0x8
#define REG_UNKNOWN1 0x1C
#define REG_OPHYTUNE 0x20
#define REG_CABLE 0x28
typedef struct IPodTouchUSBPhysState {
SysBusDevice busdev;
@@ -23,6 +24,7 @@ typedef struct IPodTouchUSBPhysState {
uint32_t usb_orstcon;
uint32_t usb_unknown1;
uint32_t usb_ophytune;
bool is_cable_connected;
} IPodTouchUSBPhysState;
#endif
+102
View File
@@ -0,0 +1,102 @@
#ifndef HW_TCP_USB
#define HW_TCP_USB
/*
* USB over TCP driver.
*
* Copyright (c) 2011 Richard Ian Taylor.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "qemu/main-loop.h"
#include "hw/usb.h"
#include "hw/sysbus.h"
enum
{
tcp_usb_setup = 1 << 0,
tcp_usb_reset = 1 << 1,
tcp_usb_enumdone = 1 << 2,
};
typedef enum _tcp_usb_state_enum
{
tcp_usb_idle,
// Client
tcp_usb_read_request,
tcp_usb_write_response,
// Host
tcp_usb_write_request,
tcp_usb_read_response,
} tcp_usb_state_enum_t;
typedef struct _tcp_usb_header
{
uint8_t addr;
uint8_t ep;
uint8_t flags;
int16_t length;
} __attribute__((packed)) tcp_usb_header_t;
struct _tcp_usb_state;
typedef int (*tcp_usb_callback_t)(struct _tcp_usb_state *_status, void *_arg, tcp_usb_header_t *_hdr, char *_buffer);
typedef void (*tcp_usb_closed_t)(struct _tcp_usb_state *_state, void *_arg);
typedef struct _tcp_usb_state
{
int socket;
int closed;
tcp_usb_state_enum_t state;
tcp_usb_header_t *header;
char *buffer;
size_t amount_done;
tcp_usb_closed_t closed_callback;
tcp_usb_callback_t data_callback;
void *callback_arg;
} tcp_usb_state_t;
void tcp_usb_init(tcp_usb_state_t *_state, tcp_usb_callback_t _cb, tcp_usb_closed_t _closed, void *_arg);
void tcp_usb_cleanup(tcp_usb_state_t *_state);
int tcp_usb_closed(tcp_usb_state_t *_state);
int tcp_usb_connect(tcp_usb_state_t *_state, char *_host, uint32_t _port);
int tcp_usb_request(tcp_usb_state_t *_state, tcp_usb_header_t *_header, const char *_data);
typedef struct _tcp_usb_host_state
{
int socket;
} tcp_usb_host_state_t;
void tcp_usb_host_init(tcp_usb_host_state_t *_state);
void tcp_usb_host_cleanup(tcp_usb_host_state_t *_state);
int tcp_usb_host_okay(tcp_usb_host_state_t *_state);
int tcp_usb_host(tcp_usb_host_state_t *_state, uint32_t _port);
int tcp_usb_accept(tcp_usb_host_state_t *_host, tcp_usb_state_t *_client);
#endif //HW_TCP_USB