Statistics
| Branch: | Revision:

root / hw / exynos4_boards.c @ 0b944384

History | View | Annotate | Download (5.8 kB)

1
/*
2
 *  Samsung exynos4 SoC based boards emulation
3
 *
4
 *  Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
5
 *    Maksim Kozlov <m.kozlov@samsung.com>
6
 *    Evgeny Voevodin <e.voevodin@samsung.com>
7
 *    Igor Mitsyanko  <i.mitsyanko@samsung.com>
8
 *
9
 *  This program is free software; you can redistribute it and/or modify it
10
 *  under the terms of the GNU General Public License as published by the
11
 *  Free Software Foundation; either version 2 of the License, or
12
 *  (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful, but WITHOUT
15
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
 *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17
 *  for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License along
20
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23

    
24
#include "sysemu.h"
25
#include "sysbus.h"
26
#include "net.h"
27
#include "arm-misc.h"
28
#include "exec-memory.h"
29
#include "exynos4210.h"
30
#include "boards.h"
31

    
32
#undef DEBUG
33

    
34
//#define DEBUG
35

    
36
#ifdef DEBUG
37
    #undef PRINT_DEBUG
38
    #define  PRINT_DEBUG(fmt, args...) \
39
        do { \
40
            fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
41
        } while (0)
42
#else
43
    #define  PRINT_DEBUG(fmt, args...)  do {} while (0)
44
#endif
45

    
46
#define SMDK_LAN9118_BASE_ADDR      0x05000000
47

    
48
typedef enum Exynos4BoardType {
49
    EXYNOS4_BOARD_NURI,
50
    EXYNOS4_BOARD_SMDKC210,
51
    EXYNOS4_NUM_OF_BOARDS
52
} Exynos4BoardType;
53

    
54
static int exynos4_board_id[EXYNOS4_NUM_OF_BOARDS] = {
55
    [EXYNOS4_BOARD_NURI]     = 0xD33,
56
    [EXYNOS4_BOARD_SMDKC210] = 0xB16,
57
};
58

    
59
static int exynos4_board_smp_bootreg_addr[EXYNOS4_NUM_OF_BOARDS] = {
60
    [EXYNOS4_BOARD_NURI]     = EXYNOS4210_SECOND_CPU_BOOTREG,
61
    [EXYNOS4_BOARD_SMDKC210] = EXYNOS4210_SECOND_CPU_BOOTREG,
62
};
63

    
64
static unsigned long exynos4_board_ram_size[EXYNOS4_NUM_OF_BOARDS] = {
65
    [EXYNOS4_BOARD_NURI]     = 0x40000000,
66
    [EXYNOS4_BOARD_SMDKC210] = 0x40000000,
67
};
68

    
69
static struct arm_boot_info exynos4_board_binfo = {
70
    .loader_start     = EXYNOS4210_BASE_BOOT_ADDR,
71
    .smp_loader_start = EXYNOS4210_SMP_BOOT_ADDR,
72
    .nb_cpus          = EXYNOS4210_NCPUS,
73
    .write_secondary_boot = exynos4210_write_secondary,
74
};
75

    
76
static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS];
77

    
78
static void lan9215_init(uint32_t base, qemu_irq irq)
79
{
80
    DeviceState *dev;
81
    SysBusDevice *s;
82

    
83
    /* This should be a 9215 but the 9118 is close enough */
84
    if (nd_table[0].vlan) {
85
        qemu_check_nic_model(&nd_table[0], "lan9118");
86
        dev = qdev_create(NULL, "lan9118");
87
        qdev_set_nic_properties(dev, &nd_table[0]);
88
        qdev_prop_set_uint32(dev, "mode_16bit", 1);
89
        qdev_init_nofail(dev);
90
        s = sysbus_from_qdev(dev);
91
        sysbus_mmio_map(s, 0, base);
92
        sysbus_connect_irq(s, 0, irq);
93
    }
94
}
95

    
96
static Exynos4210State *exynos4_boards_init_common(
97
        const char *kernel_filename,
98
        const char *kernel_cmdline,
99
        const char *initrd_filename,
100
        Exynos4BoardType board_type)
101
{
102
    if (smp_cpus != EXYNOS4210_NCPUS) {
103
        fprintf(stderr, "%s board supports only %d CPU cores. Ignoring smp_cpus"
104
                " value.\n",
105
                exynos4_machines[board_type].name,
106
                exynos4_machines[board_type].max_cpus);
107
    }
108

    
109
    exynos4_board_binfo.ram_size = exynos4_board_ram_size[board_type];
110
    exynos4_board_binfo.board_id = exynos4_board_id[board_type];
111
    exynos4_board_binfo.smp_bootreg_addr =
112
            exynos4_board_smp_bootreg_addr[board_type];
113
    exynos4_board_binfo.kernel_filename = kernel_filename;
114
    exynos4_board_binfo.initrd_filename = initrd_filename;
115
    exynos4_board_binfo.kernel_cmdline = kernel_cmdline;
116
    exynos4_board_binfo.gic_cpu_if_addr =
117
            EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100;
118

    
119
    PRINT_DEBUG("\n ram_size: %luMiB [0x%08lx]\n"
120
            " kernel_filename: %s\n"
121
            " kernel_cmdline: %s\n"
122
            " initrd_filename: %s\n",
123
            exynos4_board_ram_size[board_type] / 1048576,
124
            exynos4_board_ram_size[board_type],
125
            kernel_filename,
126
            kernel_cmdline,
127
            initrd_filename);
128

    
129
    return exynos4210_init(get_system_memory(),
130
            exynos4_board_ram_size[board_type]);
131
}
132

    
133
static void nuri_init(ram_addr_t ram_size,
134
        const char *boot_device,
135
        const char *kernel_filename, const char *kernel_cmdline,
136
        const char *initrd_filename, const char *cpu_model)
137
{
138
    exynos4_boards_init_common(kernel_filename, kernel_cmdline,
139
                initrd_filename, EXYNOS4_BOARD_NURI);
140

    
141
    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
142
}
143

    
144
static void smdkc210_init(ram_addr_t ram_size,
145
        const char *boot_device,
146
        const char *kernel_filename, const char *kernel_cmdline,
147
        const char *initrd_filename, const char *cpu_model)
148
{
149
    Exynos4210State *s = exynos4_boards_init_common(kernel_filename,
150
            kernel_cmdline, initrd_filename, EXYNOS4_BOARD_SMDKC210);
151

    
152
    lan9215_init(SMDK_LAN9118_BASE_ADDR,
153
            qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)]));
154
    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
155
}
156

    
157
static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
158
    [EXYNOS4_BOARD_NURI] = {
159
        .name = "nuri",
160
        .desc = "Samsung NURI board (Exynos4210)",
161
        .init = nuri_init,
162
        .max_cpus = EXYNOS4210_NCPUS,
163
    },
164
    [EXYNOS4_BOARD_SMDKC210] = {
165
        .name = "smdkc210",
166
        .desc = "Samsung SMDKC210 board (Exynos4210)",
167
        .init = smdkc210_init,
168
        .max_cpus = EXYNOS4210_NCPUS,
169
    },
170
};
171

    
172
static void exynos4_machine_init(void)
173
{
174
    qemu_register_machine(&exynos4_machines[EXYNOS4_BOARD_NURI]);
175
    qemu_register_machine(&exynos4_machines[EXYNOS4_BOARD_SMDKC210]);
176
}
177

    
178
machine_init(exynos4_machine_init);