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 | ... | ... |