Commit 89cdb6af04c16c5476221b1f2d25d8337ebbb391
1 parent
e33d8cdb
Provide basic emulation for Sharp SL-6000 PDA (Tosa), Dmitry Baryshkov.
This adds basic support for emulating Sharp Zaurus SL-6000 PDA (tosa). Currently it provides only basic support: no kbd/lcd, sound, ts, etc. But it's able at least to boot Linux from CF. Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4643 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
7 changed files
with
183 additions
and
15 deletions
Makefile.target
| @@ -585,7 +585,7 @@ OBJS+= arm-semi.o | @@ -585,7 +585,7 @@ OBJS+= arm-semi.o | ||
| 585 | OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o | 585 | OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o |
| 586 | OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o | 586 | OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o |
| 587 | OBJS+= pflash_cfi01.o gumstix.o | 587 | OBJS+= pflash_cfi01.o gumstix.o |
| 588 | -OBJS+= spitz.o zaurus.o ide.o serial.o nand.o ecc.o | 588 | +OBJS+= zaurus.o ide.o serial.o nand.o ecc.o spitz.o tosa.o |
| 589 | OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o | 589 | OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o |
| 590 | OBJS+= omap2.o omap_dss.o | 590 | OBJS+= omap2.o omap_dss.o |
| 591 | OBJS+= palm.o tsc210x.o | 591 | OBJS+= palm.o tsc210x.o |
hw/boards.h
| @@ -111,4 +111,7 @@ extern QEMUMachine mainstone2_machine; | @@ -111,4 +111,7 @@ extern QEMUMachine mainstone2_machine; | ||
| 111 | /* musicpal.c */ | 111 | /* musicpal.c */ |
| 112 | extern QEMUMachine musicpal_machine; | 112 | extern QEMUMachine musicpal_machine; |
| 113 | 113 | ||
| 114 | +/* tosa.c */ | ||
| 115 | +extern QEMUMachine tosapda_machine; | ||
| 116 | + | ||
| 114 | #endif | 117 | #endif |
hw/sharpsl.h
| 1 | +/* | ||
| 2 | + * Common declarations for the Zaurii. | ||
| 3 | + * | ||
| 4 | + * This file is licensed under the GNU GPL. | ||
| 5 | + */ | ||
| 1 | #ifndef QEMU_SHARPSL_H | 6 | #ifndef QEMU_SHARPSL_H |
| 2 | #define QEMU_SHARPSL_H | 7 | #define QEMU_SHARPSL_H |
| 3 | 8 | ||
| 9 | +#define zaurus_printf(format, ...) \ | ||
| 10 | + fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__) | ||
| 11 | + | ||
| 4 | /* zaurus.c */ | 12 | /* zaurus.c */ |
| 5 | struct scoop_info_s *scoop_init(struct pxa2xx_state_s *cpu, | 13 | struct scoop_info_s *scoop_init(struct pxa2xx_state_s *cpu, |
| 6 | int instance, target_phys_addr_t target_base); | 14 | int instance, target_phys_addr_t target_base); |
hw/spitz.c
| @@ -22,8 +22,6 @@ | @@ -22,8 +22,6 @@ | ||
| 22 | #include "audio/audio.h" | 22 | #include "audio/audio.h" |
| 23 | #include "boards.h" | 23 | #include "boards.h" |
| 24 | 24 | ||
| 25 | -#define spitz_printf(format, ...) \ | ||
| 26 | - fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__) | ||
| 27 | #undef REG_FMT | 25 | #undef REG_FMT |
| 28 | #if TARGET_PHYS_ADDR_BITS == 32 | 26 | #if TARGET_PHYS_ADDR_BITS == 32 |
| 29 | #define REG_FMT "0x%02x" | 27 | #define REG_FMT "0x%02x" |
| @@ -90,7 +88,7 @@ static uint32_t sl_readb(void *opaque, target_phys_addr_t addr) | @@ -90,7 +88,7 @@ static uint32_t sl_readb(void *opaque, target_phys_addr_t addr) | ||
| 90 | return ecc_digest(&s->ecc, nand_getio(s->nand)); | 88 | return ecc_digest(&s->ecc, nand_getio(s->nand)); |
| 91 | 89 | ||
| 92 | default: | 90 | default: |
| 93 | - spitz_printf("Bad register offset " REG_FMT "\n", addr); | 91 | + zaurus_printf("Bad register offset " REG_FMT "\n", addr); |
| 94 | } | 92 | } |
| 95 | return 0; | 93 | return 0; |
| 96 | } | 94 | } |
| @@ -134,7 +132,7 @@ static void sl_writeb(void *opaque, target_phys_addr_t addr, | @@ -134,7 +132,7 @@ static void sl_writeb(void *opaque, target_phys_addr_t addr, | ||
| 134 | break; | 132 | break; |
| 135 | 133 | ||
| 136 | default: | 134 | default: |
| 137 | - spitz_printf("Bad register offset " REG_FMT "\n", addr); | 135 | + zaurus_printf("Bad register offset " REG_FMT "\n", addr); |
| 138 | } | 136 | } |
| 139 | } | 137 | } |
| 140 | 138 | ||
| @@ -537,9 +535,9 @@ static int bl_intensity, bl_power; | @@ -537,9 +535,9 @@ static int bl_intensity, bl_power; | ||
| 537 | static void spitz_bl_update(struct pxa2xx_state_s *s) | 535 | static void spitz_bl_update(struct pxa2xx_state_s *s) |
| 538 | { | 536 | { |
| 539 | if (bl_power && bl_intensity) | 537 | if (bl_power && bl_intensity) |
| 540 | - spitz_printf("LCD Backlight now at %i/63\n", bl_intensity); | 538 | + zaurus_printf("LCD Backlight now at %i/63\n", bl_intensity); |
| 541 | else | 539 | else |
| 542 | - spitz_printf("LCD Backlight now off\n"); | 540 | + zaurus_printf("LCD Backlight now off\n"); |
| 543 | } | 541 | } |
| 544 | 542 | ||
| 545 | static inline void spitz_bl_bit5(void *opaque, int line, int level) | 543 | static inline void spitz_bl_bit5(void *opaque, int line, int level) |
| @@ -570,9 +568,9 @@ static void spitz_lcdtg_dac_put(void *opaque, uint8_t cmd) | @@ -570,9 +568,9 @@ static void spitz_lcdtg_dac_put(void *opaque, uint8_t cmd) | ||
| 570 | switch (addr) { | 568 | switch (addr) { |
| 571 | case LCDTG_RESCTL: | 569 | case LCDTG_RESCTL: |
| 572 | if (value) | 570 | if (value) |
| 573 | - spitz_printf("LCD in QVGA mode\n"); | 571 | + zaurus_printf("LCD in QVGA mode\n"); |
| 574 | else | 572 | else |
| 575 | - spitz_printf("LCD in VGA mode\n"); | 573 | + zaurus_printf("LCD in VGA mode\n"); |
| 576 | break; | 574 | break; |
| 577 | 575 | ||
| 578 | case LCDTG_DUTYCTRL: | 576 | case LCDTG_DUTYCTRL: |
| @@ -780,16 +778,16 @@ static void spitz_out_switch(void *opaque, int line, int level) | @@ -780,16 +778,16 @@ static void spitz_out_switch(void *opaque, int line, int level) | ||
| 780 | { | 778 | { |
| 781 | switch (line) { | 779 | switch (line) { |
| 782 | case 0: | 780 | case 0: |
| 783 | - spitz_printf("Charging %s.\n", level ? "off" : "on"); | 781 | + zaurus_printf("Charging %s.\n", level ? "off" : "on"); |
| 784 | break; | 782 | break; |
| 785 | case 1: | 783 | case 1: |
| 786 | - spitz_printf("Discharging %s.\n", level ? "on" : "off"); | 784 | + zaurus_printf("Discharging %s.\n", level ? "on" : "off"); |
| 787 | break; | 785 | break; |
| 788 | case 2: | 786 | case 2: |
| 789 | - spitz_printf("Green LED %s.\n", level ? "on" : "off"); | 787 | + zaurus_printf("Green LED %s.\n", level ? "on" : "off"); |
| 790 | break; | 788 | break; |
| 791 | case 3: | 789 | case 3: |
| 792 | - spitz_printf("Orange LED %s.\n", level ? "on" : "off"); | 790 | + zaurus_printf("Orange LED %s.\n", level ? "on" : "off"); |
| 793 | break; | 791 | break; |
| 794 | case 4: | 792 | case 4: |
| 795 | spitz_bl_bit5(opaque, line, level); | 793 | spitz_bl_bit5(opaque, line, level); |
hw/tosa.c
0 โ 100644
| 1 | +/* vim:set shiftwidth=4 ts=4 et: */ | ||
| 2 | +/* | ||
| 3 | + * PXA255 Sharp Zaurus SL-6000 PDA platform | ||
| 4 | + * | ||
| 5 | + * Copyright (c) 2008 Dmitry Baryshkov | ||
| 6 | + * | ||
| 7 | + * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org> | ||
| 8 | + * This code is licensed under the GNU GPL v2. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +#include "hw.h" | ||
| 12 | +#include "pxa.h" | ||
| 13 | +#include "arm-misc.h" | ||
| 14 | +#include "sysemu.h" | ||
| 15 | +#include "sharpsl.h" | ||
| 16 | +#include "pcmcia.h" | ||
| 17 | +#include "block.h" | ||
| 18 | +#include "boards.h" | ||
| 19 | + | ||
| 20 | +#define TOSA_RAM 0x04000000 | ||
| 21 | +#define TOSA_ROM 0x00800000 | ||
| 22 | + | ||
| 23 | +#define TOSA_GPIO_nSD_DETECT (9) | ||
| 24 | +#define TOSA_GPIO_ON_RESET (19) | ||
| 25 | +#define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */ | ||
| 26 | +#define TOSA_GPIO_CF_CD (13) | ||
| 27 | +#define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */ | ||
| 28 | + | ||
| 29 | +#define TOSA_SCOOP_GPIO_BASE 0 | ||
| 30 | +#define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2) | ||
| 31 | +#define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3) | ||
| 32 | +#define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4) | ||
| 33 | + | ||
| 34 | +struct tc6393xb_s { | ||
| 35 | + target_phys_addr_t target_base; | ||
| 36 | +}; | ||
| 37 | + | ||
| 38 | +static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) | ||
| 39 | +{ | ||
| 40 | + return 3; | ||
| 41 | +} | ||
| 42 | +static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, | ||
| 43 | + uint32_t value) | ||
| 44 | +{ | ||
| 45 | +} | ||
| 46 | +static void tosa_tc6393xb_register(struct pxa2xx_state_s *cpu) | ||
| 47 | +{ | ||
| 48 | + int iomemtype; | ||
| 49 | + struct tc6393xb_s *s; | ||
| 50 | + CPUReadMemoryFunc *tc6393xb_readfn[] = { | ||
| 51 | + tc6393xb_readb, | ||
| 52 | + tc6393xb_readb, | ||
| 53 | + tc6393xb_readb, | ||
| 54 | + }; | ||
| 55 | + CPUWriteMemoryFunc *tc6393xb_writefn[] = { | ||
| 56 | + tc6393xb_writeb, | ||
| 57 | + tc6393xb_writeb, | ||
| 58 | + tc6393xb_writeb, | ||
| 59 | + }; | ||
| 60 | + | ||
| 61 | + s = (struct tc6393xb_s *) qemu_mallocz(sizeof(struct tc6393xb_s)); | ||
| 62 | + s->target_base = 0x10000000; | ||
| 63 | + | ||
| 64 | + iomemtype = cpu_register_io_memory(0, tc6393xb_readfn, | ||
| 65 | + tc6393xb_writefn, s); | ||
| 66 | + cpu_register_physical_memory(s->target_base, 0x200000, iomemtype); | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +static void tosa_microdrive_attach(struct pxa2xx_state_s *cpu) | ||
| 70 | +{ | ||
| 71 | + struct pcmcia_card_s *md; | ||
| 72 | + int index; | ||
| 73 | + BlockDriverState *bs; | ||
| 74 | + | ||
| 75 | + index = drive_get_index(IF_IDE, 0, 0); | ||
| 76 | + if (index == -1) | ||
| 77 | + return; | ||
| 78 | + bs = drives_table[index].bdrv; | ||
| 79 | + if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) { | ||
| 80 | + md = dscm1xxxx_init(bs); | ||
| 81 | + pxa2xx_pcmcia_attach(cpu->pcmcia[0], md); | ||
| 82 | + } | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +static void tosa_gpio_setup(struct pxa2xx_state_s *cpu, | ||
| 86 | + struct scoop_info_s *scp0, | ||
| 87 | + struct scoop_info_s *scp1) | ||
| 88 | +{ | ||
| 89 | + /* MMC/SD host */ | ||
| 90 | + pxa2xx_mmci_handlers(cpu->mmc, | ||
| 91 | + scoop_gpio_in_get(scp0)[TOSA_GPIO_SD_WP], | ||
| 92 | + qemu_irq_invert(pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_nSD_DETECT])); | ||
| 93 | + | ||
| 94 | + /* Handle reset */ | ||
| 95 | + pxa2xx_gpio_out_set(cpu->gpio, TOSA_GPIO_ON_RESET, cpu->reset); | ||
| 96 | + | ||
| 97 | + /* PCMCIA signals: card's IRQ and Card-Detect */ | ||
| 98 | + pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0], | ||
| 99 | + pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_CF_IRQ], | ||
| 100 | + pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_CF_CD]); | ||
| 101 | + | ||
| 102 | + pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[1], | ||
| 103 | + pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_JC_CF_IRQ], | ||
| 104 | + NULL); | ||
| 105 | + | ||
| 106 | +} | ||
| 107 | + | ||
| 108 | +static struct arm_boot_info tosa_binfo = { | ||
| 109 | + .loader_start = PXA2XX_SDRAM_BASE, | ||
| 110 | + .ram_size = 0x04000000, | ||
| 111 | +}; | ||
| 112 | + | ||
| 113 | +static void tosa_init(ram_addr_t ram_size, int vga_ram_size, | ||
| 114 | + const char *boot_device, DisplayState *ds, | ||
| 115 | + const char *kernel_filename, const char *kernel_cmdline, | ||
| 116 | + const char *initrd_filename, const char *cpu_model) | ||
| 117 | +{ | ||
| 118 | + struct pxa2xx_state_s *cpu; | ||
| 119 | + struct scoop_info_s *scp0, *scp1; | ||
| 120 | + | ||
| 121 | + if (ram_size < (TOSA_RAM + TOSA_ROM + PXA2XX_INTERNAL_SIZE)) { | ||
| 122 | + fprintf(stderr, "This platform requires %i bytes of memory\n", | ||
| 123 | + TOSA_RAM + TOSA_ROM + PXA2XX_INTERNAL_SIZE); | ||
| 124 | + exit(1); | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + if (!cpu_model) | ||
| 128 | + cpu_model = "pxa255"; | ||
| 129 | + | ||
| 130 | + cpu = pxa255_init(tosa_binfo.ram_size, ds); | ||
| 131 | + | ||
| 132 | + cpu_register_physical_memory(0, TOSA_ROM, | ||
| 133 | + qemu_ram_alloc(TOSA_ROM) | IO_MEM_ROM); | ||
| 134 | + | ||
| 135 | + tosa_tc6393xb_register(cpu); | ||
| 136 | + | ||
| 137 | + scp0 = scoop_init(cpu, 0, 0x08800000); | ||
| 138 | + scp1 = scoop_init(cpu, 1, 0x14800040); | ||
| 139 | + | ||
| 140 | + tosa_gpio_setup(cpu, scp0, scp1); | ||
| 141 | + | ||
| 142 | + tosa_microdrive_attach(cpu); | ||
| 143 | + | ||
| 144 | + /* Setup initial (reset) machine state */ | ||
| 145 | + cpu->env->regs[15] = tosa_binfo.loader_start; | ||
| 146 | + | ||
| 147 | + tosa_binfo.kernel_filename = kernel_filename; | ||
| 148 | + tosa_binfo.kernel_cmdline = kernel_cmdline; | ||
| 149 | + tosa_binfo.initrd_filename = initrd_filename; | ||
| 150 | + tosa_binfo.board_id = 0x208; | ||
| 151 | + arm_load_kernel(cpu->env, &tosa_binfo); | ||
| 152 | + sl_bootparam_write(SL_PXA_PARAM_BASE - PXA2XX_SDRAM_BASE); | ||
| 153 | +} | ||
| 154 | + | ||
| 155 | +QEMUMachine tosapda_machine = { | ||
| 156 | + "tosa", | ||
| 157 | + "Tosa PDA (PXA255)", | ||
| 158 | + tosa_init, | ||
| 159 | + TOSA_RAM + TOSA_ROM + PXA2XX_INTERNAL_SIZE + RAMSIZE_FIXED, | ||
| 160 | +}; |
hw/zaurus.c
| @@ -21,8 +21,6 @@ | @@ -21,8 +21,6 @@ | ||
| 21 | #include "pxa.h" | 21 | #include "pxa.h" |
| 22 | #include "sharpsl.h" | 22 | #include "sharpsl.h" |
| 23 | 23 | ||
| 24 | -#define zaurus_printf(format, ...) \ | ||
| 25 | - fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__) | ||
| 26 | #undef REG_FMT | 24 | #undef REG_FMT |
| 27 | #if TARGET_PHYS_ADDR_BITS == 32 | 25 | #if TARGET_PHYS_ADDR_BITS == 32 |
| 28 | #define REG_FMT "0x%02x" | 26 | #define REG_FMT "0x%02x" |
target-arm/machine.c
| @@ -20,6 +20,7 @@ void register_machines(void) | @@ -20,6 +20,7 @@ void register_machines(void) | ||
| 20 | qemu_register_machine(&verdex_machine); | 20 | qemu_register_machine(&verdex_machine); |
| 21 | qemu_register_machine(&mainstone2_machine); | 21 | qemu_register_machine(&mainstone2_machine); |
| 22 | qemu_register_machine(&musicpal_machine); | 22 | qemu_register_machine(&musicpal_machine); |
| 23 | + qemu_register_machine(&tosapda_machine); | ||
| 23 | } | 24 | } |
| 24 | 25 | ||
| 25 | void cpu_save(QEMUFile *f, void *opaque) | 26 | void cpu_save(QEMUFile *f, void *opaque) |