Statistics
| Branch: | Revision:

root / hw / arm / exynos4_boards.c @ 0d09e41a

History | View | Annotate | Download (5.5 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/sysemu.h"
25
#include "hw/sysbus.h"
26
#include "net/net.h"
27
#include "hw/arm.h"
28
#include "exec/address-spaces.h"
29
#include "hw/arm/exynos4210.h"
30
#include "hw/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].used) {
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 = SYS_BUS_DEVICE(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(QEMUMachineInitArgs *args,
97
                                                   Exynos4BoardType board_type)
98
{
99
    if (smp_cpus != EXYNOS4210_NCPUS) {
100
        fprintf(stderr, "%s board supports only %d CPU cores. Ignoring smp_cpus"
101
                " value.\n",
102
                exynos4_machines[board_type].name,
103
                exynos4_machines[board_type].max_cpus);
104
    }
105

    
106
    exynos4_board_binfo.ram_size = exynos4_board_ram_size[board_type];
107
    exynos4_board_binfo.board_id = exynos4_board_id[board_type];
108
    exynos4_board_binfo.smp_bootreg_addr =
109
            exynos4_board_smp_bootreg_addr[board_type];
110
    exynos4_board_binfo.kernel_filename = args->kernel_filename;
111
    exynos4_board_binfo.initrd_filename = args->initrd_filename;
112
    exynos4_board_binfo.kernel_cmdline = args->kernel_cmdline;
113
    exynos4_board_binfo.gic_cpu_if_addr =
114
            EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100;
115

    
116
    PRINT_DEBUG("\n ram_size: %luMiB [0x%08lx]\n"
117
            " kernel_filename: %s\n"
118
            " kernel_cmdline: %s\n"
119
            " initrd_filename: %s\n",
120
            exynos4_board_ram_size[board_type] / 1048576,
121
            exynos4_board_ram_size[board_type],
122
            args->kernel_filename,
123
            args->kernel_cmdline,
124
            args->initrd_filename);
125

    
126
    return exynos4210_init(get_system_memory(),
127
            exynos4_board_ram_size[board_type]);
128
}
129

    
130
static void nuri_init(QEMUMachineInitArgs *args)
131
{
132
    exynos4_boards_init_common(args, EXYNOS4_BOARD_NURI);
133

    
134
    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
135
}
136

    
137
static void smdkc210_init(QEMUMachineInitArgs *args)
138
{
139
    Exynos4210State *s = exynos4_boards_init_common(args,
140
                                                    EXYNOS4_BOARD_SMDKC210);
141

    
142
    lan9215_init(SMDK_LAN9118_BASE_ADDR,
143
            qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)]));
144
    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
145
}
146

    
147
static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
148
    [EXYNOS4_BOARD_NURI] = {
149
        .name = "nuri",
150
        .desc = "Samsung NURI board (Exynos4210)",
151
        .init = nuri_init,
152
        .max_cpus = EXYNOS4210_NCPUS,
153
        DEFAULT_MACHINE_OPTIONS,
154
    },
155
    [EXYNOS4_BOARD_SMDKC210] = {
156
        .name = "smdkc210",
157
        .desc = "Samsung SMDKC210 board (Exynos4210)",
158
        .init = smdkc210_init,
159
        .max_cpus = EXYNOS4210_NCPUS,
160
        DEFAULT_MACHINE_OPTIONS,
161
    },
162
};
163

    
164
static void exynos4_machine_init(void)
165
{
166
    qemu_register_machine(&exynos4_machines[EXYNOS4_BOARD_NURI]);
167
    qemu_register_machine(&exynos4_machines[EXYNOS4_BOARD_SMDKC210]);
168
}
169

    
170
machine_init(exynos4_machine_init);