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 | 470 | VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o |
| 471 | 471 | VL_OBJS+= piix_pci.o parallel.o cirrus_vga.o $(SOUND_HW) |
| 472 | 472 | VL_OBJS+= mipsnet.o |
| 473 | +VL_OBJS+= pflash_cfi01.o | |
| 473 | 474 | CPPFLAGS += -DHAS_AUDIO |
| 474 | 475 | endif |
| 475 | 476 | ifeq ($(TARGET_BASE_ARCH), cris) | ... | ... |
hw/mips_malta.c
| ... | ... | @@ -28,6 +28,8 @@ |
| 28 | 28 | #include "net.h" |
| 29 | 29 | #include "boards.h" |
| 30 | 30 | #include "smbus.h" |
| 31 | +#include "block.h" | |
| 32 | +#include "flash.h" | |
| 31 | 33 | #include "mips.h" |
| 32 | 34 | #include "pci.h" |
| 33 | 35 | #include "qemu-char.h" |
| ... | ... | @@ -35,6 +37,8 @@ |
| 35 | 37 | #include "audio/audio.h" |
| 36 | 38 | #include "boards.h" |
| 37 | 39 | |
| 40 | +//#define DEBUG_BOARD_INIT | |
| 41 | + | |
| 38 | 42 | #ifdef TARGET_WORDS_BIGENDIAN |
| 39 | 43 | #define BIOS_FILENAME "mips_bios.bin" |
| 40 | 44 | #else |
| ... | ... | @@ -766,13 +770,13 @@ void mips_malta_init (int ram_size, int vga_ram_size, |
| 766 | 770 | { |
| 767 | 771 | char buf[1024]; |
| 768 | 772 | unsigned long bios_offset; |
| 773 | + target_long bios_size; | |
| 769 | 774 | int64_t kernel_entry; |
| 770 | 775 | PCIBus *pci_bus; |
| 771 | 776 | CPUState *env; |
| 772 | 777 | RTCState *rtc_state; |
| 773 | 778 | fdctrl_t *floppy_controller; |
| 774 | 779 | MaltaFPGAState *malta_fpga; |
| 775 | - int ret; | |
| 776 | 780 | qemu_irq *i8259; |
| 777 | 781 | int piix4_devfn; |
| 778 | 782 | uint8_t *eeprom_buf; |
| ... | ... | @@ -781,6 +785,8 @@ void mips_malta_init (int ram_size, int vga_ram_size, |
| 781 | 785 | int index; |
| 782 | 786 | BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; |
| 783 | 787 | BlockDriverState *fd[MAX_FD]; |
| 788 | + int fl_idx = 0; | |
| 789 | + int fl_sectors = 0; | |
| 784 | 790 | |
| 785 | 791 | /* init CPUs */ |
| 786 | 792 | if (cpu_model == NULL) { |
| ... | ... | @@ -801,7 +807,7 @@ void mips_malta_init (int ram_size, int vga_ram_size, |
| 801 | 807 | /* allocate RAM */ |
| 802 | 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 | 811 | bios_offset = ram_size + vga_ram_size; |
| 806 | 812 | cpu_register_physical_memory(0x1e000000LL, |
| 807 | 813 | BIOS_SIZE, bios_offset | IO_MEM_ROM); |
| ... | ... | @@ -811,17 +817,44 @@ void mips_malta_init (int ram_size, int vga_ram_size, |
| 811 | 817 | /* FPGA */ |
| 812 | 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 | 859 | /* In little endian mode the 32bit words in the bios are swapped, |
| 827 | 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 | 862 | { |
| 830 | 863 | uint32_t *addr; |
| 831 | 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 | 867 | *addr = bswap32(*addr); |
| 835 | 868 | } |
| 836 | 869 | } |
| 837 | 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 | 873 | /* Board ID = 0x420 (Malta Board with CoreLV) |
| 853 | 874 | XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should |
| 854 | 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 | 111 | else if (pfl->width == 4) |
| 112 | 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 | 117 | switch (pfl->cmd) { |
| 118 | 118 | case 0x00: |
| ... | ... | @@ -121,7 +121,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) |
| 121 | 121 | switch (width) { |
| 122 | 122 | case 1: |
| 123 | 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 | 126 | break; |
| 126 | 127 | case 2: |
| 127 | 128 | #if defined(TARGET_WORDS_BIGENDIAN) |
| ... | ... | @@ -131,7 +132,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) |
| 131 | 132 | ret = p[offset]; |
| 132 | 133 | ret |= p[offset + 1] << 8; |
| 133 | 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 | 137 | break; |
| 136 | 138 | case 4: |
| 137 | 139 | #if defined(TARGET_WORDS_BIGENDIAN) |
| ... | ... | @@ -146,7 +148,8 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) |
| 146 | 148 | ret |= p[offset + 2] << 16; |
| 147 | 149 | ret |= p[offset + 3] << 24; |
| 148 | 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 | 153 | break; |
| 151 | 154 | default: |
| 152 | 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 | 211 | else |
| 209 | 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 | 217 | /* Set the device in I/O access mode */ |
| 215 | 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 | 233 | p = pfl->storage; |
| 231 | 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 | 240 | memset(p + offset, 0xff, pfl->sector_len); |
| 237 | 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 | 282 | |
| 279 | 283 | break; |
| 280 | 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 | 286 | pfl->counter = cmd; |
| 283 | 287 | pfl->wcycle++; |
| 284 | 288 | break; |
| ... | ... | @@ -311,8 +315,9 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, |
| 311 | 315 | switch (pfl->cmd) { |
| 312 | 316 | case 0xe8: /* Block write */ |
| 313 | 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 | 321 | switch (width) { |
| 317 | 322 | case 1: |
| 318 | 323 | p[offset] = value; |
| ... | ... | @@ -382,8 +387,8 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, |
| 382 | 387 | |
| 383 | 388 | error_flash: |
| 384 | 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 | 393 | reset_flash: |
| 389 | 394 | cpu_register_physical_memory(pfl->base, pfl->total_len, |
| ... | ... | @@ -484,7 +489,7 @@ static int ctz32 (uint32_t n) |
| 484 | 489 | } |
| 485 | 490 | |
| 486 | 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 | 493 | int nb_blocs, int width, |
| 489 | 494 | uint16_t id0, uint16_t id1, |
| 490 | 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 | 500 | total_len = sector_len * nb_blocs; |
| 496 | 501 | |
| 497 | 502 | /* XXX: to be fixed */ |
| 503 | +#if 0 | |
| 498 | 504 | if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) && |
| 499 | 505 | total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024)) |
| 500 | 506 | return NULL; |
| 507 | +#endif | |
| 501 | 508 | |
| 502 | 509 | pfl = qemu_mallocz(sizeof(pflash_t)); |
| 503 | 510 | ... | ... |