root / hw / arm / digic_boards.c @ 20bcf73f
History | View | Annotate | Download (4.6 kB)
1 | d91fd756 | Antony Pavlov | /*
|
---|---|---|---|
2 | d91fd756 | Antony Pavlov | * QEMU model of the Canon DIGIC boards (cameras indeed :).
|
3 | d91fd756 | Antony Pavlov | *
|
4 | d91fd756 | Antony Pavlov | * Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
|
5 | d91fd756 | Antony Pavlov | *
|
6 | d91fd756 | Antony Pavlov | * This model is based on reverse engineering efforts
|
7 | d91fd756 | Antony Pavlov | * made by CHDK (http://chdk.wikia.com) and
|
8 | d91fd756 | Antony Pavlov | * Magic Lantern (http://www.magiclantern.fm) projects
|
9 | d91fd756 | Antony Pavlov | * contributors.
|
10 | d91fd756 | Antony Pavlov | *
|
11 | d91fd756 | Antony Pavlov | * See docs here:
|
12 | d91fd756 | Antony Pavlov | * http://magiclantern.wikia.com/wiki/Register_Map
|
13 | d91fd756 | Antony Pavlov | *
|
14 | d91fd756 | Antony Pavlov | * This program is free software; you can redistribute it and/or modify
|
15 | d91fd756 | Antony Pavlov | * it under the terms of the GNU General Public License as published by
|
16 | d91fd756 | Antony Pavlov | * the Free Software Foundation; either version 2 of the License, or
|
17 | d91fd756 | Antony Pavlov | * (at your option) any later version.
|
18 | d91fd756 | Antony Pavlov | *
|
19 | d91fd756 | Antony Pavlov | * This program is distributed in the hope that it will be useful,
|
20 | d91fd756 | Antony Pavlov | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
21 | d91fd756 | Antony Pavlov | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
22 | d91fd756 | Antony Pavlov | * GNU General Public License for more details.
|
23 | d91fd756 | Antony Pavlov | *
|
24 | d91fd756 | Antony Pavlov | */
|
25 | d91fd756 | Antony Pavlov | |
26 | d91fd756 | Antony Pavlov | #include "hw/boards.h" |
27 | d91fd756 | Antony Pavlov | #include "exec/address-spaces.h" |
28 | d91fd756 | Antony Pavlov | #include "qemu/error-report.h" |
29 | d91fd756 | Antony Pavlov | #include "hw/arm/digic.h" |
30 | 04234a37 | Antony Pavlov | #include "hw/block/flash.h" |
31 | 04234a37 | Antony Pavlov | #include "hw/loader.h" |
32 | 04234a37 | Antony Pavlov | #include "sysemu/sysemu.h" |
33 | 04234a37 | Antony Pavlov | #include "sysemu/qtest.h" |
34 | 04234a37 | Antony Pavlov | |
35 | 04234a37 | Antony Pavlov | #define DIGIC4_ROM0_BASE 0xf0000000 |
36 | 04234a37 | Antony Pavlov | #define DIGIC4_ROM1_BASE 0xf8000000 |
37 | 04234a37 | Antony Pavlov | #define DIGIC4_ROM_MAX_SIZE 0x08000000 |
38 | d91fd756 | Antony Pavlov | |
39 | d91fd756 | Antony Pavlov | typedef struct DigicBoardState { |
40 | d91fd756 | Antony Pavlov | DigicState *digic; |
41 | d91fd756 | Antony Pavlov | MemoryRegion ram; |
42 | d91fd756 | Antony Pavlov | } DigicBoardState; |
43 | d91fd756 | Antony Pavlov | |
44 | d91fd756 | Antony Pavlov | typedef struct DigicBoard { |
45 | d91fd756 | Antony Pavlov | hwaddr ram_size; |
46 | 04234a37 | Antony Pavlov | void (*add_rom0)(DigicBoardState *, hwaddr, const char *); |
47 | 04234a37 | Antony Pavlov | const char *rom0_def_filename; |
48 | 04234a37 | Antony Pavlov | void (*add_rom1)(DigicBoardState *, hwaddr, const char *); |
49 | 04234a37 | Antony Pavlov | const char *rom1_def_filename; |
50 | d91fd756 | Antony Pavlov | } DigicBoard; |
51 | d91fd756 | Antony Pavlov | |
52 | d91fd756 | Antony Pavlov | static void digic4_board_setup_ram(DigicBoardState *s, hwaddr ram_size) |
53 | d91fd756 | Antony Pavlov | { |
54 | d91fd756 | Antony Pavlov | memory_region_init_ram(&s->ram, NULL, "ram", ram_size); |
55 | d91fd756 | Antony Pavlov | memory_region_add_subregion(get_system_memory(), 0, &s->ram);
|
56 | d91fd756 | Antony Pavlov | vmstate_register_ram_global(&s->ram); |
57 | d91fd756 | Antony Pavlov | } |
58 | d91fd756 | Antony Pavlov | |
59 | d91fd756 | Antony Pavlov | static void digic4_board_init(DigicBoard *board) |
60 | d91fd756 | Antony Pavlov | { |
61 | d91fd756 | Antony Pavlov | Error *err = NULL;
|
62 | d91fd756 | Antony Pavlov | |
63 | d91fd756 | Antony Pavlov | DigicBoardState *s = g_new(DigicBoardState, 1);
|
64 | d91fd756 | Antony Pavlov | |
65 | d91fd756 | Antony Pavlov | s->digic = DIGIC(object_new(TYPE_DIGIC)); |
66 | d91fd756 | Antony Pavlov | object_property_set_bool(OBJECT(s->digic), true, "realized", &err); |
67 | d91fd756 | Antony Pavlov | if (err != NULL) { |
68 | d91fd756 | Antony Pavlov | error_report("Couldn't realize DIGIC SoC: %s\n",
|
69 | d91fd756 | Antony Pavlov | error_get_pretty(err)); |
70 | d91fd756 | Antony Pavlov | exit(1);
|
71 | d91fd756 | Antony Pavlov | } |
72 | d91fd756 | Antony Pavlov | |
73 | d91fd756 | Antony Pavlov | digic4_board_setup_ram(s, board->ram_size); |
74 | 04234a37 | Antony Pavlov | |
75 | 04234a37 | Antony Pavlov | if (board->add_rom0) {
|
76 | 04234a37 | Antony Pavlov | board->add_rom0(s, DIGIC4_ROM0_BASE, board->rom0_def_filename); |
77 | 04234a37 | Antony Pavlov | } |
78 | 04234a37 | Antony Pavlov | |
79 | 04234a37 | Antony Pavlov | if (board->add_rom1) {
|
80 | 04234a37 | Antony Pavlov | board->add_rom1(s, DIGIC4_ROM1_BASE, board->rom1_def_filename); |
81 | 04234a37 | Antony Pavlov | } |
82 | 04234a37 | Antony Pavlov | } |
83 | 04234a37 | Antony Pavlov | |
84 | 04234a37 | Antony Pavlov | static void digic_load_rom(DigicBoardState *s, hwaddr addr, |
85 | 04234a37 | Antony Pavlov | hwaddr max_size, const char *def_filename) |
86 | 04234a37 | Antony Pavlov | { |
87 | 04234a37 | Antony Pavlov | target_long rom_size; |
88 | 04234a37 | Antony Pavlov | const char *filename; |
89 | 04234a37 | Antony Pavlov | |
90 | 04234a37 | Antony Pavlov | if (qtest_enabled()) {
|
91 | 04234a37 | Antony Pavlov | /* qtest runs no code so don't attempt a ROM load which
|
92 | 04234a37 | Antony Pavlov | * could fail and result in a spurious test failure.
|
93 | 04234a37 | Antony Pavlov | */
|
94 | 04234a37 | Antony Pavlov | return;
|
95 | 04234a37 | Antony Pavlov | } |
96 | 04234a37 | Antony Pavlov | |
97 | 04234a37 | Antony Pavlov | if (bios_name) {
|
98 | 04234a37 | Antony Pavlov | filename = bios_name; |
99 | 04234a37 | Antony Pavlov | } else {
|
100 | 04234a37 | Antony Pavlov | filename = def_filename; |
101 | 04234a37 | Antony Pavlov | } |
102 | 04234a37 | Antony Pavlov | |
103 | 04234a37 | Antony Pavlov | if (filename) {
|
104 | 04234a37 | Antony Pavlov | char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
|
105 | 04234a37 | Antony Pavlov | |
106 | 04234a37 | Antony Pavlov | if (!fn) {
|
107 | 04234a37 | Antony Pavlov | error_report("Couldn't find rom image '%s'.\n", filename);
|
108 | 04234a37 | Antony Pavlov | exit(1);
|
109 | 04234a37 | Antony Pavlov | } |
110 | 04234a37 | Antony Pavlov | |
111 | 04234a37 | Antony Pavlov | rom_size = load_image_targphys(fn, addr, max_size); |
112 | 04234a37 | Antony Pavlov | if (rom_size < 0 || rom_size > max_size) { |
113 | 04234a37 | Antony Pavlov | error_report("Couldn't load rom image '%s'.\n", filename);
|
114 | 04234a37 | Antony Pavlov | exit(1);
|
115 | 04234a37 | Antony Pavlov | } |
116 | 04234a37 | Antony Pavlov | } |
117 | 04234a37 | Antony Pavlov | } |
118 | 04234a37 | Antony Pavlov | |
119 | 04234a37 | Antony Pavlov | /*
|
120 | 04234a37 | Antony Pavlov | * Samsung K8P3215UQB
|
121 | 04234a37 | Antony Pavlov | * 64M Bit (4Mx16) Page Mode / Multi-Bank NOR Flash Memory
|
122 | 04234a37 | Antony Pavlov | */
|
123 | 04234a37 | Antony Pavlov | static void digic4_add_k8p3215uqb_rom(DigicBoardState *s, hwaddr addr, |
124 | 04234a37 | Antony Pavlov | const char *def_filename) |
125 | 04234a37 | Antony Pavlov | { |
126 | 04234a37 | Antony Pavlov | #define FLASH_K8P3215UQB_SIZE (4 * 1024 * 1024) |
127 | 04234a37 | Antony Pavlov | #define FLASH_K8P3215UQB_SECTOR_SIZE (64 * 1024) |
128 | 04234a37 | Antony Pavlov | |
129 | 04234a37 | Antony Pavlov | pflash_cfi02_register(addr, NULL, "pflash", FLASH_K8P3215UQB_SIZE, |
130 | 04234a37 | Antony Pavlov | NULL, FLASH_K8P3215UQB_SECTOR_SIZE,
|
131 | 04234a37 | Antony Pavlov | FLASH_K8P3215UQB_SIZE / FLASH_K8P3215UQB_SECTOR_SIZE, |
132 | 04234a37 | Antony Pavlov | DIGIC4_ROM_MAX_SIZE / FLASH_K8P3215UQB_SIZE, |
133 | 04234a37 | Antony Pavlov | 4,
|
134 | 04234a37 | Antony Pavlov | 0x00EC, 0x007E, 0x0003, 0x0001, |
135 | 04234a37 | Antony Pavlov | 0x0555, 0x2aa, 0); |
136 | 04234a37 | Antony Pavlov | |
137 | 04234a37 | Antony Pavlov | digic_load_rom(s, addr, FLASH_K8P3215UQB_SIZE, def_filename); |
138 | d91fd756 | Antony Pavlov | } |
139 | d91fd756 | Antony Pavlov | |
140 | d91fd756 | Antony Pavlov | static DigicBoard digic4_board_canon_a1100 = {
|
141 | d91fd756 | Antony Pavlov | .ram_size = 64 * 1024 * 1024, |
142 | 04234a37 | Antony Pavlov | .add_rom1 = digic4_add_k8p3215uqb_rom, |
143 | 04234a37 | Antony Pavlov | .rom1_def_filename = "canon-a1100-rom1.bin",
|
144 | d91fd756 | Antony Pavlov | }; |
145 | d91fd756 | Antony Pavlov | |
146 | d91fd756 | Antony Pavlov | static void canon_a1100_init(QEMUMachineInitArgs *args) |
147 | d91fd756 | Antony Pavlov | { |
148 | d91fd756 | Antony Pavlov | digic4_board_init(&digic4_board_canon_a1100); |
149 | d91fd756 | Antony Pavlov | } |
150 | d91fd756 | Antony Pavlov | |
151 | d91fd756 | Antony Pavlov | static QEMUMachine canon_a1100 = {
|
152 | d91fd756 | Antony Pavlov | .name = "canon-a1100",
|
153 | d91fd756 | Antony Pavlov | .desc = "Canon PowerShot A1100 IS",
|
154 | d91fd756 | Antony Pavlov | .init = &canon_a1100_init, |
155 | d91fd756 | Antony Pavlov | }; |
156 | d91fd756 | Antony Pavlov | |
157 | d91fd756 | Antony Pavlov | static void digic_register_machines(void) |
158 | d91fd756 | Antony Pavlov | { |
159 | d91fd756 | Antony Pavlov | qemu_register_machine(&canon_a1100); |
160 | d91fd756 | Antony Pavlov | } |
161 | d91fd756 | Antony Pavlov | |
162 | d91fd756 | Antony Pavlov | machine_init(digic_register_machines) |