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