* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "hw.h"
-#include "pxa.h"
#include "sharpsl.h"
+#include "sysbus.h"
#undef REG_FMT
-#if TARGET_PHYS_ADDR_BITS == 32
-#define REG_FMT "0x%02x"
-#else
#define REG_FMT "0x%02lx"
-#endif
/* SCOOP devices */
-struct scoop_info_s {
+typedef struct ScoopInfo ScoopInfo;
+struct ScoopInfo {
+ SysBusDevice busdev;
qemu_irq handler[16];
- qemu_irq *in;
uint16_t status;
uint16_t power;
uint32_t gpio_level;
#define SCOOP_GPWR 0x24
#define SCOOP_GPRR 0x28
-static inline void scoop_gpio_handler_update(struct scoop_info_s *s) {
+static inline void scoop_gpio_handler_update(ScoopInfo *s) {
uint32_t level, diff;
int bit;
level = s->gpio_level & s->gpio_dir;
static uint32_t scoop_readb(void *opaque, target_phys_addr_t addr)
{
- struct scoop_info_s *s = (struct scoop_info_s *) opaque;
+ ScoopInfo *s = (ScoopInfo *) opaque;
- switch (addr) {
+ switch (addr & 0x3f) {
case SCOOP_MCR:
return s->mcr;
case SCOOP_CDR:
case SCOOP_GPRR:
return s->gpio_level;
default:
- zaurus_printf("Bad register offset " REG_FMT "\n", addr);
+ zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
}
return 0;
static void scoop_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
{
- struct scoop_info_s *s = (struct scoop_info_s *) opaque;
+ ScoopInfo *s = (ScoopInfo *) opaque;
value &= 0xffff;
- switch (addr) {
+ switch (addr & 0x3f) {
case SCOOP_MCR:
s->mcr = value;
break;
scoop_gpio_handler_update(s);
break;
default:
- zaurus_printf("Bad register offset " REG_FMT "\n", addr);
+ zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
}
}
-static CPUReadMemoryFunc *scoop_readfn[] = {
+static CPUReadMemoryFunc * const scoop_readfn[] = {
scoop_readb,
scoop_readb,
scoop_readb,
};
-static CPUWriteMemoryFunc *scoop_writefn[] = {
+static CPUWriteMemoryFunc * const scoop_writefn[] = {
scoop_writeb,
scoop_writeb,
scoop_writeb,
};
-void scoop_gpio_set(void *opaque, int line, int level)
+static void scoop_gpio_set(void *opaque, int line, int level)
{
- struct scoop_info_s *s = (struct scoop_info_s *) s;
+ ScoopInfo *s = (ScoopInfo *) opaque;
if (level)
s->gpio_level |= (1 << line);
s->gpio_level &= ~(1 << line);
}
-qemu_irq *scoop_gpio_in_get(struct scoop_info_s *s)
+static int scoop_init(SysBusDevice *dev)
{
- return s->in;
-}
+ ScoopInfo *s = FROM_SYSBUS(ScoopInfo, dev);
+ int iomemtype;
-void scoop_gpio_out_set(struct scoop_info_s *s, int line,
- qemu_irq handler) {
- if (line >= 16) {
- fprintf(stderr, "No GPIO pin %i\n", line);
- exit(-1);
- }
+ s->status = 0x02;
+ qdev_init_gpio_out(&s->busdev.qdev, s->handler, 16);
+ qdev_init_gpio_in(&s->busdev.qdev, scoop_gpio_set, 16);
+ iomemtype = cpu_register_io_memory(scoop_readfn,
+ scoop_writefn, s, DEVICE_NATIVE_ENDIAN);
- s->handler[line] = handler;
-}
+ sysbus_init_mmio(dev, 0x1000, iomemtype);
-static void scoop_save(QEMUFile *f, void *opaque)
-{
- struct scoop_info_s *s = (struct scoop_info_s *) opaque;
- qemu_put_be16s(f, &s->status);
- qemu_put_be16s(f, &s->power);
- qemu_put_be32s(f, &s->gpio_level);
- qemu_put_be32s(f, &s->gpio_dir);
- qemu_put_be32s(f, &s->prev_level);
- qemu_put_be16s(f, &s->mcr);
- qemu_put_be16s(f, &s->cdr);
- qemu_put_be16s(f, &s->ccr);
- qemu_put_be16s(f, &s->irr);
- qemu_put_be16s(f, &s->imr);
- qemu_put_be16s(f, &s->isr);
+ return 0;
}
-static int scoop_load(QEMUFile *f, void *opaque, int version_id)
+static int scoop_post_load(void *opaque, int version_id)
{
- uint16_t dummy;
- struct scoop_info_s *s = (struct scoop_info_s *) opaque;
- qemu_get_be16s(f, &s->status);
- qemu_get_be16s(f, &s->power);
- qemu_get_be32s(f, &s->gpio_level);
- qemu_get_be32s(f, &s->gpio_dir);
- qemu_get_be32s(f, &s->prev_level);
- qemu_get_be16s(f, &s->mcr);
- qemu_get_be16s(f, &s->cdr);
- qemu_get_be16s(f, &s->ccr);
- qemu_get_be16s(f, &s->irr);
- qemu_get_be16s(f, &s->imr);
- qemu_get_be16s(f, &s->isr);
- if (version_id < 1)
- qemu_get_be16s(f, &dummy);
+ ScoopInfo *s = (ScoopInfo *) opaque;
+ int i;
+ uint32_t level;
+
+ level = s->gpio_level & s->gpio_dir;
+
+ for (i = 0; i < 16; i++) {
+ qemu_set_irq(s->handler[i], (level >> i) & 1);
+ }
+
+ s->prev_level = level;
return 0;
}
-struct scoop_info_s *scoop_init(struct pxa2xx_state_s *cpu,
- int instance,
- target_phys_addr_t target_base) {
- int iomemtype;
- struct scoop_info_s *s;
+static bool is_version_0 (void *opaque, int version_id)
+{
+ return version_id == 0;
+}
- s = (struct scoop_info_s *)
- qemu_mallocz(sizeof(struct scoop_info_s));
- memset(s, 0, sizeof(struct scoop_info_s));
+static const VMStateDescription vmstate_scoop_regs = {
+ .name = "scoop",
+ .version_id = 1,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .post_load = scoop_post_load,
+ .fields = (VMStateField []) {
+ VMSTATE_UINT16(status, ScoopInfo),
+ VMSTATE_UINT16(power, ScoopInfo),
+ VMSTATE_UINT32(gpio_level, ScoopInfo),
+ VMSTATE_UINT32(gpio_dir, ScoopInfo),
+ VMSTATE_UINT32(prev_level, ScoopInfo),
+ VMSTATE_UINT16(mcr, ScoopInfo),
+ VMSTATE_UINT16(cdr, ScoopInfo),
+ VMSTATE_UINT16(ccr, ScoopInfo),
+ VMSTATE_UINT16(irr, ScoopInfo),
+ VMSTATE_UINT16(imr, ScoopInfo),
+ VMSTATE_UINT16(isr, ScoopInfo),
+ VMSTATE_UNUSED_TEST(is_version_0, 2),
+ VMSTATE_END_OF_LIST(),
+ },
+};
- s->status = 0x02;
- s->in = qemu_allocate_irqs(scoop_gpio_set, s, 16);
- iomemtype = cpu_register_io_memory(0, scoop_readfn,
- scoop_writefn, s);
- cpu_register_physical_memory(target_base, 0x1000, iomemtype);
- register_savevm("scoop", instance, 1, scoop_save, scoop_load, s);
+static SysBusDeviceInfo scoop_sysbus_info = {
+ .init = scoop_init,
+ .qdev.name = "scoop",
+ .qdev.desc = "Scoop2 Sharp custom ASIC",
+ .qdev.size = sizeof(ScoopInfo),
+ .qdev.vmsd = &vmstate_scoop_regs,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_END_OF_LIST(),
+ }
+};
- return s;
+static void scoop_register(void)
+{
+ sysbus_register_withprop(&scoop_sysbus_info);
}
+device_init(scoop_register);
/* Write the bootloader parameters memory area. */