Commit 52b437377fdf2749bed30243e921974cef3c422b
1 parent
7ffab4d7
Use guest memory access functions when setting up arm boorloader.
Signed-off-by: Paul Brook <paul@codesourcery.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7053 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
83 additions
and
67 deletions
hw/arm_boot.c
| ... | ... | @@ -53,124 +53,135 @@ static void main_cpu_reset(void *opaque) |
| 53 | 53 | /* TODO: Reset secondary CPUs. */ |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | +#define WRITE_WORD(p, value) do { \ | |
| 57 | + stl_phys_notdirty(p, value); \ | |
| 58 | + p += 4; \ | |
| 59 | +} while (0) | |
| 60 | + | |
| 56 | 61 | static void set_kernel_args(struct arm_boot_info *info, |
| 57 | - int initrd_size, void *base) | |
| 62 | + int initrd_size, target_phys_addr_t base) | |
| 58 | 63 | { |
| 59 | - uint32_t *p; | |
| 64 | + target_phys_addr_t p; | |
| 60 | 65 | |
| 61 | - p = (uint32_t *)(base + KERNEL_ARGS_ADDR); | |
| 66 | + p = base + KERNEL_ARGS_ADDR; | |
| 62 | 67 | /* ATAG_CORE */ |
| 63 | - stl_raw(p++, 5); | |
| 64 | - stl_raw(p++, 0x54410001); | |
| 65 | - stl_raw(p++, 1); | |
| 66 | - stl_raw(p++, 0x1000); | |
| 67 | - stl_raw(p++, 0); | |
| 68 | + WRITE_WORD(p, 5); | |
| 69 | + WRITE_WORD(p, 0x54410001); | |
| 70 | + WRITE_WORD(p, 1); | |
| 71 | + WRITE_WORD(p, 0x1000); | |
| 72 | + WRITE_WORD(p, 0); | |
| 68 | 73 | /* ATAG_MEM */ |
| 69 | 74 | /* TODO: handle multiple chips on one ATAG list */ |
| 70 | - stl_raw(p++, 4); | |
| 71 | - stl_raw(p++, 0x54410002); | |
| 72 | - stl_raw(p++, info->ram_size); | |
| 73 | - stl_raw(p++, info->loader_start); | |
| 75 | + WRITE_WORD(p, 4); | |
| 76 | + WRITE_WORD(p, 0x54410002); | |
| 77 | + WRITE_WORD(p, info->ram_size); | |
| 78 | + WRITE_WORD(p, info->loader_start); | |
| 74 | 79 | if (initrd_size) { |
| 75 | 80 | /* ATAG_INITRD2 */ |
| 76 | - stl_raw(p++, 4); | |
| 77 | - stl_raw(p++, 0x54420005); | |
| 78 | - stl_raw(p++, info->loader_start + INITRD_LOAD_ADDR); | |
| 79 | - stl_raw(p++, initrd_size); | |
| 81 | + WRITE_WORD(p, 4); | |
| 82 | + WRITE_WORD(p, 0x54420005); | |
| 83 | + WRITE_WORD(p, info->loader_start + INITRD_LOAD_ADDR); | |
| 84 | + WRITE_WORD(p, initrd_size); | |
| 80 | 85 | } |
| 81 | 86 | if (info->kernel_cmdline && *info->kernel_cmdline) { |
| 82 | 87 | /* ATAG_CMDLINE */ |
| 83 | 88 | int cmdline_size; |
| 84 | 89 | |
| 85 | 90 | cmdline_size = strlen(info->kernel_cmdline); |
| 86 | - memcpy(p + 2, info->kernel_cmdline, cmdline_size + 1); | |
| 91 | + cpu_physical_memory_write(p + 8, (void *)info->kernel_cmdline, | |
| 92 | + cmdline_size + 1); | |
| 87 | 93 | cmdline_size = (cmdline_size >> 2) + 1; |
| 88 | - stl_raw(p++, cmdline_size + 2); | |
| 89 | - stl_raw(p++, 0x54410009); | |
| 90 | - p += cmdline_size; | |
| 94 | + WRITE_WORD(p, cmdline_size + 2); | |
| 95 | + WRITE_WORD(p, 0x54410009); | |
| 96 | + p += cmdline_size * 4; | |
| 91 | 97 | } |
| 92 | 98 | if (info->atag_board) { |
| 93 | 99 | /* ATAG_BOARD */ |
| 94 | 100 | int atag_board_len; |
| 101 | + uint8_t atag_board_buf[0x1000]; | |
| 95 | 102 | |
| 96 | - atag_board_len = (info->atag_board(info, p + 2) + 3) >> 2; | |
| 97 | - stl_raw(p++, 2 + atag_board_len); | |
| 98 | - stl_raw(p++, 0x414f4d50); | |
| 103 | + atag_board_len = (info->atag_board(info, atag_board_buf) + 3) & ~3; | |
| 104 | + WRITE_WORD(p, (atag_board_len + 8) >> 2); | |
| 105 | + WRITE_WORD(p, 0x414f4d50); | |
| 106 | + cpu_physical_memory_write(p, atag_board_buf, atag_board_len); | |
| 99 | 107 | p += atag_board_len; |
| 100 | 108 | } |
| 101 | 109 | /* ATAG_END */ |
| 102 | - stl_raw(p++, 0); | |
| 103 | - stl_raw(p++, 0); | |
| 110 | + WRITE_WORD(p, 0); | |
| 111 | + WRITE_WORD(p, 0); | |
| 104 | 112 | } |
| 105 | 113 | |
| 106 | 114 | static void set_kernel_args_old(struct arm_boot_info *info, |
| 107 | - int initrd_size, void *base) | |
| 115 | + int initrd_size, target_phys_addr_t base) | |
| 108 | 116 | { |
| 109 | - uint32_t *p; | |
| 110 | - char *s; | |
| 117 | + target_phys_addr_t p; | |
| 118 | + const char *s; | |
| 119 | + | |
| 111 | 120 | |
| 112 | 121 | /* see linux/include/asm-arm/setup.h */ |
| 113 | - p = (uint32_t *)(base + KERNEL_ARGS_ADDR); | |
| 122 | + p = base + KERNEL_ARGS_ADDR; | |
| 114 | 123 | /* page_size */ |
| 115 | - stl_raw(p++, 4096); | |
| 124 | + WRITE_WORD(p, 4096); | |
| 116 | 125 | /* nr_pages */ |
| 117 | - stl_raw(p++, info->ram_size / 4096); | |
| 126 | + WRITE_WORD(p, info->ram_size / 4096); | |
| 118 | 127 | /* ramdisk_size */ |
| 119 | - stl_raw(p++, 0); | |
| 128 | + WRITE_WORD(p, 0); | |
| 120 | 129 | #define FLAG_READONLY 1 |
| 121 | 130 | #define FLAG_RDLOAD 4 |
| 122 | 131 | #define FLAG_RDPROMPT 8 |
| 123 | 132 | /* flags */ |
| 124 | - stl_raw(p++, FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT); | |
| 133 | + WRITE_WORD(p, FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT); | |
| 125 | 134 | /* rootdev */ |
| 126 | - stl_raw(p++, (31 << 8) | 0); /* /dev/mtdblock0 */ | |
| 135 | + WRITE_WORD(p, (31 << 8) | 0); /* /dev/mtdblock0 */ | |
| 127 | 136 | /* video_num_cols */ |
| 128 | - stl_raw(p++, 0); | |
| 137 | + WRITE_WORD(p, 0); | |
| 129 | 138 | /* video_num_rows */ |
| 130 | - stl_raw(p++, 0); | |
| 139 | + WRITE_WORD(p, 0); | |
| 131 | 140 | /* video_x */ |
| 132 | - stl_raw(p++, 0); | |
| 141 | + WRITE_WORD(p, 0); | |
| 133 | 142 | /* video_y */ |
| 134 | - stl_raw(p++, 0); | |
| 143 | + WRITE_WORD(p, 0); | |
| 135 | 144 | /* memc_control_reg */ |
| 136 | - stl_raw(p++, 0); | |
| 145 | + WRITE_WORD(p, 0); | |
| 137 | 146 | /* unsigned char sounddefault */ |
| 138 | 147 | /* unsigned char adfsdrives */ |
| 139 | 148 | /* unsigned char bytes_per_char_h */ |
| 140 | 149 | /* unsigned char bytes_per_char_v */ |
| 141 | - stl_raw(p++, 0); | |
| 150 | + WRITE_WORD(p, 0); | |
| 142 | 151 | /* pages_in_bank[4] */ |
| 143 | - stl_raw(p++, 0); | |
| 144 | - stl_raw(p++, 0); | |
| 145 | - stl_raw(p++, 0); | |
| 146 | - stl_raw(p++, 0); | |
| 152 | + WRITE_WORD(p, 0); | |
| 153 | + WRITE_WORD(p, 0); | |
| 154 | + WRITE_WORD(p, 0); | |
| 155 | + WRITE_WORD(p, 0); | |
| 147 | 156 | /* pages_in_vram */ |
| 148 | - stl_raw(p++, 0); | |
| 157 | + WRITE_WORD(p, 0); | |
| 149 | 158 | /* initrd_start */ |
| 150 | 159 | if (initrd_size) |
| 151 | - stl_raw(p++, info->loader_start + INITRD_LOAD_ADDR); | |
| 160 | + WRITE_WORD(p, info->loader_start + INITRD_LOAD_ADDR); | |
| 152 | 161 | else |
| 153 | - stl_raw(p++, 0); | |
| 162 | + WRITE_WORD(p, 0); | |
| 154 | 163 | /* initrd_size */ |
| 155 | - stl_raw(p++, initrd_size); | |
| 164 | + WRITE_WORD(p, initrd_size); | |
| 156 | 165 | /* rd_start */ |
| 157 | - stl_raw(p++, 0); | |
| 166 | + WRITE_WORD(p, 0); | |
| 158 | 167 | /* system_rev */ |
| 159 | - stl_raw(p++, 0); | |
| 168 | + WRITE_WORD(p, 0); | |
| 160 | 169 | /* system_serial_low */ |
| 161 | - stl_raw(p++, 0); | |
| 170 | + WRITE_WORD(p, 0); | |
| 162 | 171 | /* system_serial_high */ |
| 163 | - stl_raw(p++, 0); | |
| 172 | + WRITE_WORD(p, 0); | |
| 164 | 173 | /* mem_fclk_21285 */ |
| 165 | - stl_raw(p++, 0); | |
| 174 | + WRITE_WORD(p, 0); | |
| 166 | 175 | /* zero unused fields */ |
| 167 | - memset(p, 0, 256 + 1024 - | |
| 168 | - (p - ((uint32_t *)(base + KERNEL_ARGS_ADDR)))); | |
| 169 | - s = base + KERNEL_ARGS_ADDR + 256 + 1024; | |
| 170 | - if (info->kernel_cmdline) | |
| 171 | - strcpy (s, info->kernel_cmdline); | |
| 172 | - else | |
| 173 | - stb_raw(s, 0); | |
| 176 | + while (p < base + KERNEL_ARGS_ADDR + 256 + 1024) { | |
| 177 | + WRITE_WORD(p, 0); | |
| 178 | + } | |
| 179 | + s = info->kernel_cmdline; | |
| 180 | + if (s) { | |
| 181 | + cpu_physical_memory_write(p, (void *)s, strlen(s) + 1); | |
| 182 | + } else { | |
| 183 | + WRITE_WORD(p, 0); | |
| 184 | + } | |
| 174 | 185 | } |
| 175 | 186 | |
| 176 | 187 | void arm_load_kernel(CPUState *env, struct arm_boot_info *info) |
| ... | ... | @@ -197,6 +208,7 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info) |
| 197 | 208 | qemu_register_reset(main_cpu_reset, env); |
| 198 | 209 | } |
| 199 | 210 | |
| 211 | + /* FIXME: We should make load_image take a guest physical address. */ | |
| 200 | 212 | pd = cpu_get_physical_page_desc(info->loader_start); |
| 201 | 213 | loader_phys = phys_ram_base + (pd & TARGET_PAGE_MASK) + |
| 202 | 214 | (info->loader_start & ~TARGET_PAGE_MASK); |
| ... | ... | @@ -239,14 +251,17 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info) |
| 239 | 251 | bootloader[2] |= (info->board_id >> 8) & 0xff; |
| 240 | 252 | bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR; |
| 241 | 253 | bootloader[6] = entry; |
| 242 | - for (n = 0; n < sizeof(bootloader) / 4; n++) | |
| 243 | - stl_raw(loader_phys + (n * 4), bootloader[n]); | |
| 244 | - if (info->nb_cpus > 1) | |
| 245 | - for (n = 0; n < sizeof(smpboot) / 4; n++) | |
| 246 | - stl_raw(loader_phys + info->ram_size + (n * 4), smpboot[n]); | |
| 254 | + for (n = 0; n < sizeof(bootloader) / 4; n++) { | |
| 255 | + stl_phys_notdirty(info->loader_start + (n * 4), bootloader[n]); | |
| 256 | + } | |
| 257 | + if (info->nb_cpus > 1) { | |
| 258 | + for (n = 0; n < sizeof(smpboot) / 4; n++) { | |
| 259 | + stl_phys_notdirty(info->smp_loader_start + (n * 4), smpboot[n]); | |
| 260 | + } | |
| 261 | + } | |
| 247 | 262 | if (old_param) |
| 248 | - set_kernel_args_old(info, initrd_size, loader_phys); | |
| 263 | + set_kernel_args_old(info, initrd_size, info->loader_start); | |
| 249 | 264 | else |
| 250 | - set_kernel_args(info, initrd_size, loader_phys); | |
| 265 | + set_kernel_args(info, initrd_size, info->loader_start); | |
| 251 | 266 | } |
| 252 | 267 | } | ... | ... |