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