Commit c8b153d79493e83113f1eb3055de5f31f104f4c5
1 parent
b67bfe8d
Malta flash support.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3887 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
71 additions
and
42 deletions
Makefile.target
| @@ -470,6 +470,7 @@ VL_OBJS+= jazz_led.o | @@ -470,6 +470,7 @@ VL_OBJS+= jazz_led.o | ||
| 470 | VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o | 470 | VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o |
| 471 | VL_OBJS+= piix_pci.o parallel.o cirrus_vga.o $(SOUND_HW) | 471 | VL_OBJS+= piix_pci.o parallel.o cirrus_vga.o $(SOUND_HW) |
| 472 | VL_OBJS+= mipsnet.o | 472 | VL_OBJS+= mipsnet.o |
| 473 | +VL_OBJS+= pflash_cfi01.o | ||
| 473 | CPPFLAGS += -DHAS_AUDIO | 474 | CPPFLAGS += -DHAS_AUDIO |
| 474 | endif | 475 | endif |
| 475 | ifeq ($(TARGET_BASE_ARCH), cris) | 476 | ifeq ($(TARGET_BASE_ARCH), cris) |
hw/mips_malta.c
| @@ -28,6 +28,8 @@ | @@ -28,6 +28,8 @@ | ||
| 28 | #include "net.h" | 28 | #include "net.h" |
| 29 | #include "boards.h" | 29 | #include "boards.h" |
| 30 | #include "smbus.h" | 30 | #include "smbus.h" |
| 31 | +#include "block.h" | ||
| 32 | +#include "flash.h" | ||
| 31 | #include "mips.h" | 33 | #include "mips.h" |
| 32 | #include "pci.h" | 34 | #include "pci.h" |
| 33 | #include "qemu-char.h" | 35 | #include "qemu-char.h" |
| @@ -35,6 +37,8 @@ | @@ -35,6 +37,8 @@ | ||
| 35 | #include "audio/audio.h" | 37 | #include "audio/audio.h" |
| 36 | #include "boards.h" | 38 | #include "boards.h" |
| 37 | 39 | ||
| 40 | +//#define DEBUG_BOARD_INIT | ||
| 41 | + | ||
| 38 | #ifdef TARGET_WORDS_BIGENDIAN | 42 | #ifdef TARGET_WORDS_BIGENDIAN |
| 39 | #define BIOS_FILENAME "mips_bios.bin" | 43 | #define BIOS_FILENAME "mips_bios.bin" |
| 40 | #else | 44 | #else |
| @@ -766,13 +770,13 @@ void mips_malta_init (int ram_size, int vga_ram_size, | @@ -766,13 +770,13 @@ void mips_malta_init (int ram_size, int vga_ram_size, | ||
| 766 | { | 770 | { |
| 767 | char buf[1024]; | 771 | char buf[1024]; |
| 768 | unsigned long bios_offset; | 772 | unsigned long bios_offset; |
| 773 | + target_long bios_size; | ||
| 769 | int64_t kernel_entry; | 774 | int64_t kernel_entry; |
| 770 | PCIBus *pci_bus; | 775 | PCIBus *pci_bus; |
| 771 | CPUState *env; | 776 | CPUState *env; |
| 772 | RTCState *rtc_state; | 777 | RTCState *rtc_state; |
| 773 | fdctrl_t *floppy_controller; | 778 | fdctrl_t *floppy_controller; |
| 774 | MaltaFPGAState *malta_fpga; | 779 | MaltaFPGAState *malta_fpga; |
| 775 | - int ret; | ||
| 776 | qemu_irq *i8259; | 780 | qemu_irq *i8259; |
| 777 | int piix4_devfn; | 781 | int piix4_devfn; |
| 778 | uint8_t *eeprom_buf; | 782 | uint8_t *eeprom_buf; |
| @@ -781,6 +785,8 @@ void mips_malta_init (int ram_size, int vga_ram_size, | @@ -781,6 +785,8 @@ void mips_malta_init (int ram_size, int vga_ram_size, | ||
| 781 | int index; | 785 | int index; |
| 782 | BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | 786 | BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; |
| 783 | BlockDriverState *fd[MAX_FD]; | 787 | BlockDriverState *fd[MAX_FD]; |
| 788 | + int fl_idx = 0; | ||
| 789 | + int fl_sectors = 0; | ||
| 784 | 790 | ||
| 785 | /* init CPUs */ | 791 | /* init CPUs */ |
| 786 | if (cpu_model == NULL) { | 792 | if (cpu_model == NULL) { |
| @@ -801,7 +807,7 @@ void mips_malta_init (int ram_size, int vga_ram_size, | @@ -801,7 +807,7 @@ void mips_malta_init (int ram_size, int vga_ram_size, | ||
| 801 | /* allocate RAM */ | 807 | /* allocate RAM */ |
| 802 | cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); | 808 | cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); |
| 803 | 809 | ||
| 804 | - /* Map the bios at two physical locations, as on the real board */ | 810 | + /* Map the bios at two physical locations, as on the real board. */ |
| 805 | bios_offset = ram_size + vga_ram_size; | 811 | bios_offset = ram_size + vga_ram_size; |
| 806 | cpu_register_physical_memory(0x1e000000LL, | 812 | cpu_register_physical_memory(0x1e000000LL, |
| 807 | BIOS_SIZE, bios_offset | IO_MEM_ROM); | 813 | BIOS_SIZE, bios_offset | IO_MEM_ROM); |
| @@ -811,17 +817,44 @@ void mips_malta_init (int ram_size, int vga_ram_size, | @@ -811,17 +817,44 @@ void mips_malta_init (int ram_size, int vga_ram_size, | ||
| 811 | /* FPGA */ | 817 | /* FPGA */ |
| 812 | malta_fpga = malta_fpga_init(0x1f000000LL, env); | 818 | malta_fpga = malta_fpga_init(0x1f000000LL, env); |
| 813 | 819 | ||
| 814 | - /* Load a BIOS image unless a kernel image has been specified. */ | ||
| 815 | - if (!kernel_filename) { | ||
| 816 | - if (bios_name == NULL) | ||
| 817 | - bios_name = BIOS_FILENAME; | ||
| 818 | - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); | ||
| 819 | - ret = load_image(buf, phys_ram_base + bios_offset); | ||
| 820 | - if (ret < 0 || ret > BIOS_SIZE) { | ||
| 821 | - fprintf(stderr, | ||
| 822 | - "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n", | ||
| 823 | - buf); | ||
| 824 | - exit(1); | 820 | + /* Load firmware in flash / BIOS unless we boot directly into a kernel. */ |
| 821 | + if (kernel_filename) { | ||
| 822 | + /* Write a small bootloader to the flash location. */ | ||
| 823 | + loaderparams.ram_size = ram_size; | ||
| 824 | + loaderparams.kernel_filename = kernel_filename; | ||
| 825 | + loaderparams.kernel_cmdline = kernel_cmdline; | ||
| 826 | + loaderparams.initrd_filename = initrd_filename; | ||
| 827 | + kernel_entry = load_kernel(env); | ||
| 828 | + env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL)); | ||
| 829 | + write_bootloader(env, bios_offset, kernel_entry); | ||
| 830 | + } else { | ||
| 831 | + index = drive_get_index(IF_PFLASH, 0, fl_idx); | ||
| 832 | + if (index != -1) { | ||
| 833 | + /* Load firmware from flash. */ | ||
| 834 | + bios_size = 0x400000; | ||
| 835 | + fl_sectors = bios_size >> 16; | ||
| 836 | +#ifdef DEBUG_BOARD_INIT | ||
| 837 | + printf("Register parallel flash %d size " TARGET_FMT_lx " at " | ||
| 838 | + "offset %08lx addr %08llx '%s' %x\n", | ||
| 839 | + fl_idx, bios_size, bios_offset, 0x1e000000LL, | ||
| 840 | + bdrv_get_device_name(drives_table[index].bdrv), fl_sectors); | ||
| 841 | +#endif | ||
| 842 | + pflash_cfi01_register(0x1e000000LL, bios_offset, | ||
| 843 | + drives_table[index].bdrv, 65536, fl_sectors, | ||
| 844 | + 4, 0x0000, 0x0000, 0x0000, 0x0000); | ||
| 845 | + fl_idx++; | ||
| 846 | + } else { | ||
| 847 | + /* Load a BIOS image. */ | ||
| 848 | + if (bios_name == NULL) | ||
| 849 | + bios_name = BIOS_FILENAME; | ||
| 850 | + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); | ||
| 851 | + bios_size = load_image(buf, phys_ram_base + bios_offset); | ||
| 852 | + if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) { | ||
| 853 | + fprintf(stderr, | ||
| 854 | + "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n", | ||
| 855 | + buf); | ||
| 856 | + exit(1); | ||
| 857 | + } | ||
| 825 | } | 858 | } |
| 826 | /* In little endian mode the 32bit words in the bios are swapped, | 859 | /* In little endian mode the 32bit words in the bios are swapped, |
| 827 | a neat trick which allows bi-endian firmware. */ | 860 | a neat trick which allows bi-endian firmware. */ |
| @@ -829,26 +862,14 @@ void mips_malta_init (int ram_size, int vga_ram_size, | @@ -829,26 +862,14 @@ void mips_malta_init (int ram_size, int vga_ram_size, | ||
| 829 | { | 862 | { |
| 830 | uint32_t *addr; | 863 | uint32_t *addr; |
| 831 | for (addr = (uint32_t *)(phys_ram_base + bios_offset); | 864 | for (addr = (uint32_t *)(phys_ram_base + bios_offset); |
| 832 | - addr < (uint32_t *)(phys_ram_base + bios_offset + ret); | ||
| 833 | - addr++) { | 865 | + addr < (uint32_t *)(phys_ram_base + bios_offset + bios_size); |
| 866 | + addr++) { | ||
| 834 | *addr = bswap32(*addr); | 867 | *addr = bswap32(*addr); |
| 835 | } | 868 | } |
| 836 | } | 869 | } |
| 837 | #endif | 870 | #endif |
| 838 | } | 871 | } |
| 839 | 872 | ||
| 840 | - /* If a kernel image has been specified, write a small bootloader | ||
| 841 | - to the flash location. */ | ||
| 842 | - if (kernel_filename) { | ||
| 843 | - loaderparams.ram_size = ram_size; | ||
| 844 | - loaderparams.kernel_filename = kernel_filename; | ||
| 845 | - loaderparams.kernel_cmdline = kernel_cmdline; | ||
| 846 | - loaderparams.initrd_filename = initrd_filename; | ||
| 847 | - kernel_entry = load_kernel(env); | ||
| 848 | - env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL)); | ||
| 849 | - write_bootloader(env, bios_offset, kernel_entry); | ||
| 850 | - } | ||
| 851 | - | ||
| 852 | /* Board ID = 0x420 (Malta Board with CoreLV) | 873 | /* Board ID = 0x420 (Malta Board with CoreLV) |
| 853 | XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should | 874 | XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should |
| 854 | map to the board ID. */ | 875 | map to the board ID. */ |
hw/pflash_cfi01.c
| @@ -111,8 +111,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) | @@ -111,8 +111,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) | ||
| 111 | else if (pfl->width == 4) | 111 | else if (pfl->width == 4) |
| 112 | boff = boff >> 2; | 112 | boff = boff >> 2; |
| 113 | 113 | ||
| 114 | - DPRINTF("%s: reading offset %08x under cmd %02x\n", | ||
| 115 | - __func__, boff, pfl->cmd); | 114 | + DPRINTF("%s: reading offset " TARGET_FMT_lx " under cmd %02x\n", |
| 115 | + __func__, boff, pfl->cmd); | ||
| 116 | 116 | ||
| 117 | switch (pfl->cmd) { | 117 | switch (pfl->cmd) { |
| 118 | case 0x00: | 118 | case 0x00: |
| @@ -121,7 +121,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) | @@ -121,7 +121,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) | ||
| 121 | switch (width) { | 121 | switch (width) { |
| 122 | case 1: | 122 | case 1: |
| 123 | ret = p[offset]; | 123 | ret = p[offset]; |
| 124 | - DPRINTF("%s: data offset %08x %02x\n", __func__, offset, ret); | 124 | + DPRINTF("%s: data offset " TARGET_FMT_lx " %02x\n", |
| 125 | + __func__, offset, ret); | ||
| 125 | break; | 126 | break; |
| 126 | case 2: | 127 | case 2: |
| 127 | #if defined(TARGET_WORDS_BIGENDIAN) | 128 | #if defined(TARGET_WORDS_BIGENDIAN) |
| @@ -131,7 +132,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) | @@ -131,7 +132,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) | ||
| 131 | ret = p[offset]; | 132 | ret = p[offset]; |
| 132 | ret |= p[offset + 1] << 8; | 133 | ret |= p[offset + 1] << 8; |
| 133 | #endif | 134 | #endif |
| 134 | - DPRINTF("%s: data offset %08x %04x\n", __func__, offset, ret); | 135 | + DPRINTF("%s: data offset " TARGET_FMT_lx " %04x\n", |
| 136 | + __func__, offset, ret); | ||
| 135 | break; | 137 | break; |
| 136 | case 4: | 138 | case 4: |
| 137 | #if defined(TARGET_WORDS_BIGENDIAN) | 139 | #if defined(TARGET_WORDS_BIGENDIAN) |
| @@ -146,7 +148,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) | @@ -146,7 +148,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) | ||
| 146 | ret |= p[offset + 2] << 16; | 148 | ret |= p[offset + 2] << 16; |
| 147 | ret |= p[offset + 3] << 24; | 149 | ret |= p[offset + 3] << 24; |
| 148 | #endif | 150 | #endif |
| 149 | - DPRINTF("%s: data offset %08x %08x\n", __func__, offset, ret); | 151 | + DPRINTF("%s: data offset " TARGET_FMT_lx " %08x\n", |
| 152 | + __func__, offset, ret); | ||
| 150 | break; | 153 | break; |
| 151 | default: | 154 | default: |
| 152 | DPRINTF("BUG in %s\n", __func__); | 155 | DPRINTF("BUG in %s\n", __func__); |
| @@ -208,8 +211,8 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | @@ -208,8 +211,8 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | ||
| 208 | else | 211 | else |
| 209 | offset -= pfl->base; | 212 | offset -= pfl->base; |
| 210 | 213 | ||
| 211 | - DPRINTF("%s: offset %08x %08x %d wcycle 0x%x\n", | ||
| 212 | - __func__, offset, value, width, pfl->wcycle); | 214 | + DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d wcycle 0x%x\n", |
| 215 | + __func__, offset, value, width, pfl->wcycle); | ||
| 213 | 216 | ||
| 214 | /* Set the device in I/O access mode */ | 217 | /* Set the device in I/O access mode */ |
| 215 | cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem); | 218 | cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem); |
| @@ -230,8 +233,9 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | @@ -230,8 +233,9 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | ||
| 230 | p = pfl->storage; | 233 | p = pfl->storage; |
| 231 | offset &= ~(pfl->sector_len - 1); | 234 | offset &= ~(pfl->sector_len - 1); |
| 232 | 235 | ||
| 233 | - DPRINTF("%s: block erase at 0x%x bytes 0x%x\n", __func__, | ||
| 234 | - offset, pfl->sector_len); | 236 | + DPRINTF("%s: block erase at " TARGET_FMT_lx " bytes " |
| 237 | + TARGET_FMT_lx "\n", | ||
| 238 | + __func__, offset, pfl->sector_len); | ||
| 235 | 239 | ||
| 236 | memset(p + offset, 0xff, pfl->sector_len); | 240 | memset(p + offset, 0xff, pfl->sector_len); |
| 237 | pflash_update(pfl, offset, pfl->sector_len); | 241 | pflash_update(pfl, offset, pfl->sector_len); |
| @@ -278,7 +282,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | @@ -278,7 +282,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | ||
| 278 | 282 | ||
| 279 | break; | 283 | break; |
| 280 | case 0xe8: | 284 | case 0xe8: |
| 281 | - DPRINTF("%s: block write of 0x%x bytes\n", __func__, cmd); | 285 | + DPRINTF("%s: block write of %x bytes\n", __func__, cmd); |
| 282 | pfl->counter = cmd; | 286 | pfl->counter = cmd; |
| 283 | pfl->wcycle++; | 287 | pfl->wcycle++; |
| 284 | break; | 288 | break; |
| @@ -311,8 +315,9 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | @@ -311,8 +315,9 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | ||
| 311 | switch (pfl->cmd) { | 315 | switch (pfl->cmd) { |
| 312 | case 0xe8: /* Block write */ | 316 | case 0xe8: /* Block write */ |
| 313 | p = pfl->storage; | 317 | p = pfl->storage; |
| 314 | - DPRINTF("%s: block write offset 0x%x value 0x%x counter 0x%x\n", | ||
| 315 | - __func__, offset, value, pfl->counter); | 318 | + DPRINTF("%s: block write offset " TARGET_FMT_lx |
| 319 | + " value %x counter " TARGET_FMT_lx "\n", | ||
| 320 | + __func__, offset, value, pfl->counter); | ||
| 316 | switch (width) { | 321 | switch (width) { |
| 317 | case 1: | 322 | case 1: |
| 318 | p[offset] = value; | 323 | p[offset] = value; |
| @@ -382,8 +387,8 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | @@ -382,8 +387,8 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | ||
| 382 | 387 | ||
| 383 | error_flash: | 388 | error_flash: |
| 384 | printf("%s: Unimplemented flash cmd sequence " | 389 | printf("%s: Unimplemented flash cmd sequence " |
| 385 | - "(offset 0x%x, wcycle 0x%x cmd 0x%x value 0x%x\n", | ||
| 386 | - __func__, offset, pfl->wcycle, pfl->cmd, value); | 390 | + "(offset " TARGET_FMT_lx ", wcycle 0x%x cmd 0x%x value 0x%x\n", |
| 391 | + __func__, offset, pfl->wcycle, pfl->cmd, value); | ||
| 387 | 392 | ||
| 388 | reset_flash: | 393 | reset_flash: |
| 389 | cpu_register_physical_memory(pfl->base, pfl->total_len, | 394 | cpu_register_physical_memory(pfl->base, pfl->total_len, |
| @@ -484,7 +489,7 @@ static int ctz32 (uint32_t n) | @@ -484,7 +489,7 @@ static int ctz32 (uint32_t n) | ||
| 484 | } | 489 | } |
| 485 | 490 | ||
| 486 | pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, | 491 | pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, |
| 487 | - BlockDriverState *bs, target_ulong sector_len, | 492 | + BlockDriverState *bs, uint32_t sector_len, |
| 488 | int nb_blocs, int width, | 493 | int nb_blocs, int width, |
| 489 | uint16_t id0, uint16_t id1, | 494 | uint16_t id0, uint16_t id1, |
| 490 | uint16_t id2, uint16_t id3) | 495 | uint16_t id2, uint16_t id3) |
| @@ -495,9 +500,11 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, | @@ -495,9 +500,11 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, | ||
| 495 | total_len = sector_len * nb_blocs; | 500 | total_len = sector_len * nb_blocs; |
| 496 | 501 | ||
| 497 | /* XXX: to be fixed */ | 502 | /* XXX: to be fixed */ |
| 503 | +#if 0 | ||
| 498 | if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) && | 504 | if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) && |
| 499 | total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024)) | 505 | total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024)) |
| 500 | return NULL; | 506 | return NULL; |
| 507 | +#endif | ||
| 501 | 508 | ||
| 502 | pfl = qemu_mallocz(sizeof(pflash_t)); | 509 | pfl = qemu_mallocz(sizeof(pflash_t)); |
| 503 | 510 |