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,124 +53,135 @@ static void main_cpu_reset(void *opaque) | ||
| 53 | /* TODO: Reset secondary CPUs. */ | 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 | static void set_kernel_args(struct arm_boot_info *info, | 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 | /* ATAG_CORE */ | 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 | /* ATAG_MEM */ | 73 | /* ATAG_MEM */ |
| 69 | /* TODO: handle multiple chips on one ATAG list */ | 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 | if (initrd_size) { | 79 | if (initrd_size) { |
| 75 | /* ATAG_INITRD2 */ | 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 | if (info->kernel_cmdline && *info->kernel_cmdline) { | 86 | if (info->kernel_cmdline && *info->kernel_cmdline) { |
| 82 | /* ATAG_CMDLINE */ | 87 | /* ATAG_CMDLINE */ |
| 83 | int cmdline_size; | 88 | int cmdline_size; |
| 84 | 89 | ||
| 85 | cmdline_size = strlen(info->kernel_cmdline); | 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 | cmdline_size = (cmdline_size >> 2) + 1; | 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 | if (info->atag_board) { | 98 | if (info->atag_board) { |
| 93 | /* ATAG_BOARD */ | 99 | /* ATAG_BOARD */ |
| 94 | int atag_board_len; | 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 | p += atag_board_len; | 107 | p += atag_board_len; |
| 100 | } | 108 | } |
| 101 | /* ATAG_END */ | 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 | static void set_kernel_args_old(struct arm_boot_info *info, | 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 | /* see linux/include/asm-arm/setup.h */ | 121 | /* see linux/include/asm-arm/setup.h */ |
| 113 | - p = (uint32_t *)(base + KERNEL_ARGS_ADDR); | 122 | + p = base + KERNEL_ARGS_ADDR; |
| 114 | /* page_size */ | 123 | /* page_size */ |
| 115 | - stl_raw(p++, 4096); | 124 | + WRITE_WORD(p, 4096); |
| 116 | /* nr_pages */ | 125 | /* nr_pages */ |
| 117 | - stl_raw(p++, info->ram_size / 4096); | 126 | + WRITE_WORD(p, info->ram_size / 4096); |
| 118 | /* ramdisk_size */ | 127 | /* ramdisk_size */ |
| 119 | - stl_raw(p++, 0); | 128 | + WRITE_WORD(p, 0); |
| 120 | #define FLAG_READONLY 1 | 129 | #define FLAG_READONLY 1 |
| 121 | #define FLAG_RDLOAD 4 | 130 | #define FLAG_RDLOAD 4 |
| 122 | #define FLAG_RDPROMPT 8 | 131 | #define FLAG_RDPROMPT 8 |
| 123 | /* flags */ | 132 | /* flags */ |
| 124 | - stl_raw(p++, FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT); | 133 | + WRITE_WORD(p, FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT); |
| 125 | /* rootdev */ | 134 | /* rootdev */ |
| 126 | - stl_raw(p++, (31 << 8) | 0); /* /dev/mtdblock0 */ | 135 | + WRITE_WORD(p, (31 << 8) | 0); /* /dev/mtdblock0 */ |
| 127 | /* video_num_cols */ | 136 | /* video_num_cols */ |
| 128 | - stl_raw(p++, 0); | 137 | + WRITE_WORD(p, 0); |
| 129 | /* video_num_rows */ | 138 | /* video_num_rows */ |
| 130 | - stl_raw(p++, 0); | 139 | + WRITE_WORD(p, 0); |
| 131 | /* video_x */ | 140 | /* video_x */ |
| 132 | - stl_raw(p++, 0); | 141 | + WRITE_WORD(p, 0); |
| 133 | /* video_y */ | 142 | /* video_y */ |
| 134 | - stl_raw(p++, 0); | 143 | + WRITE_WORD(p, 0); |
| 135 | /* memc_control_reg */ | 144 | /* memc_control_reg */ |
| 136 | - stl_raw(p++, 0); | 145 | + WRITE_WORD(p, 0); |
| 137 | /* unsigned char sounddefault */ | 146 | /* unsigned char sounddefault */ |
| 138 | /* unsigned char adfsdrives */ | 147 | /* unsigned char adfsdrives */ |
| 139 | /* unsigned char bytes_per_char_h */ | 148 | /* unsigned char bytes_per_char_h */ |
| 140 | /* unsigned char bytes_per_char_v */ | 149 | /* unsigned char bytes_per_char_v */ |
| 141 | - stl_raw(p++, 0); | 150 | + WRITE_WORD(p, 0); |
| 142 | /* pages_in_bank[4] */ | 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 | /* pages_in_vram */ | 156 | /* pages_in_vram */ |
| 148 | - stl_raw(p++, 0); | 157 | + WRITE_WORD(p, 0); |
| 149 | /* initrd_start */ | 158 | /* initrd_start */ |
| 150 | if (initrd_size) | 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 | else | 161 | else |
| 153 | - stl_raw(p++, 0); | 162 | + WRITE_WORD(p, 0); |
| 154 | /* initrd_size */ | 163 | /* initrd_size */ |
| 155 | - stl_raw(p++, initrd_size); | 164 | + WRITE_WORD(p, initrd_size); |
| 156 | /* rd_start */ | 165 | /* rd_start */ |
| 157 | - stl_raw(p++, 0); | 166 | + WRITE_WORD(p, 0); |
| 158 | /* system_rev */ | 167 | /* system_rev */ |
| 159 | - stl_raw(p++, 0); | 168 | + WRITE_WORD(p, 0); |
| 160 | /* system_serial_low */ | 169 | /* system_serial_low */ |
| 161 | - stl_raw(p++, 0); | 170 | + WRITE_WORD(p, 0); |
| 162 | /* system_serial_high */ | 171 | /* system_serial_high */ |
| 163 | - stl_raw(p++, 0); | 172 | + WRITE_WORD(p, 0); |
| 164 | /* mem_fclk_21285 */ | 173 | /* mem_fclk_21285 */ |
| 165 | - stl_raw(p++, 0); | 174 | + WRITE_WORD(p, 0); |
| 166 | /* zero unused fields */ | 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 | void arm_load_kernel(CPUState *env, struct arm_boot_info *info) | 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,6 +208,7 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info) | ||
| 197 | qemu_register_reset(main_cpu_reset, env); | 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 | pd = cpu_get_physical_page_desc(info->loader_start); | 212 | pd = cpu_get_physical_page_desc(info->loader_start); |
| 201 | loader_phys = phys_ram_base + (pd & TARGET_PAGE_MASK) + | 213 | loader_phys = phys_ram_base + (pd & TARGET_PAGE_MASK) + |
| 202 | (info->loader_start & ~TARGET_PAGE_MASK); | 214 | (info->loader_start & ~TARGET_PAGE_MASK); |
| @@ -239,14 +251,17 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info) | @@ -239,14 +251,17 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info) | ||
| 239 | bootloader[2] |= (info->board_id >> 8) & 0xff; | 251 | bootloader[2] |= (info->board_id >> 8) & 0xff; |
| 240 | bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR; | 252 | bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR; |
| 241 | bootloader[6] = entry; | 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 | if (old_param) | 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 | else | 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 | } |
hw/realview.c