1/*
2 * Copyright (c) 2002-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Ali Saidi
29 */
30
31#include "arch/sparc/system.hh"
32
33#include "arch/vtophys.hh"
34#include "base/loader/object_file.hh"
35#include "base/loader/symtab.hh"
36#include "base/trace.hh"
37#include "mem/physical.hh"
38#include "params/SparcSystem.hh"
39#include "sim/byteswap.hh"
40
41using namespace BigEndianGuest;
42
43SparcSystem::SparcSystem(Params *p)
44    : System(p), sysTick(0)
45{
46    resetSymtab = new SymbolTable;
47    hypervisorSymtab = new SymbolTable;
48    openbootSymtab = new SymbolTable;
49    nvramSymtab = new SymbolTable;
50    hypervisorDescSymtab = new SymbolTable;
51    partitionDescSymtab = new SymbolTable;
52
53    /**
54     * Load the boot code, and hypervisor into memory.
55     */
56    // Read the reset binary
57    reset = createObjectFile(params()->reset_bin, true);
58    if (reset == NULL)
59        fatal("Could not load reset binary %s", params()->reset_bin);
60
61    // Read the openboot binary
62    openboot = createObjectFile(params()->openboot_bin, true);
63    if (openboot == NULL)
64        fatal("Could not load openboot bianry %s", params()->openboot_bin);
65
66    // Read the hypervisor binary
67    hypervisor = createObjectFile(params()->hypervisor_bin, true);
68    if (hypervisor == NULL)
69        fatal("Could not load hypervisor binary %s", params()->hypervisor_bin);
70
71    // Read the nvram image
72    nvram = createObjectFile(params()->nvram_bin, true);
73    if (nvram == NULL)
74        fatal("Could not load nvram image %s", params()->nvram_bin);
75
76    // Read the hypervisor description image
77    hypervisor_desc = createObjectFile(params()->hypervisor_desc_bin, true);
78    if (hypervisor_desc == NULL)
79        fatal("Could not load hypervisor description image %s",
80                params()->hypervisor_desc_bin);
81
82    // Read the partition description image
83    partition_desc = createObjectFile(params()->partition_desc_bin, true);
84    if (partition_desc == NULL)
85        fatal("Could not load partition description image %s",
86                params()->partition_desc_bin);
87
88    // load symbols
89    if (!reset->loadGlobalSymbols(resetSymtab))
90        panic("could not load reset symbols\n");
91
92    if (!openboot->loadGlobalSymbols(openbootSymtab))
93        panic("could not load openboot symbols\n");
94
95    if (!hypervisor->loadLocalSymbols(hypervisorSymtab))
96        panic("could not load hypervisor symbols\n");
97
98    if (!nvram->loadLocalSymbols(nvramSymtab))
99        panic("could not load nvram symbols\n");
100
101    if (!hypervisor_desc->loadLocalSymbols(hypervisorDescSymtab))
102        panic("could not load hypervisor description symbols\n");
103
104    if (!partition_desc->loadLocalSymbols(partitionDescSymtab))
105        panic("could not load partition description symbols\n");
106
107    // load symbols into debug table
108    if (!reset->loadGlobalSymbols(debugSymbolTable))
109        panic("could not load reset symbols\n");
110
111    if (!openboot->loadGlobalSymbols(debugSymbolTable))
112        panic("could not load openboot symbols\n");
113
114    if (!hypervisor->loadLocalSymbols(debugSymbolTable))
115        panic("could not load hypervisor symbols\n");
116
117    // Strip off the rom address so when the hypervisor is copied into memory we
118    // have symbols still
119    if (!hypervisor->loadLocalSymbols(debugSymbolTable, 0, 0, 0xFFFFFF))
120        panic("could not load hypervisor symbols\n");
121
122    if (!nvram->loadGlobalSymbols(debugSymbolTable))
123        panic("could not load reset symbols\n");
124
125    if (!hypervisor_desc->loadGlobalSymbols(debugSymbolTable))
126        panic("could not load hypervisor description symbols\n");
127
128    if (!partition_desc->loadLocalSymbols(debugSymbolTable))
129        panic("could not load partition description symbols\n");
130
131}
132
133void
134SparcSystem::initState()
135{
136    // Call the initialisation of the super class
137    System::initState();
138
139    // Load reset binary into memory
140    reset->setTextBase(params()->reset_addr);
141    reset->loadSections(physProxy);
142    // Load the openboot binary
143    openboot->setTextBase(params()->openboot_addr);
144    openboot->loadSections(physProxy);
145    // Load the hypervisor binary
146    hypervisor->setTextBase(params()->hypervisor_addr);
147    hypervisor->loadSections(physProxy);
148    // Load the nvram image
149    nvram->setTextBase(params()->nvram_addr);
150    nvram->loadSections(physProxy);
151    // Load the hypervisor description image
152    hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
153    hypervisor_desc->loadSections(physProxy);
154    // Load the partition description image
155    partition_desc->setTextBase(params()->partition_desc_addr);
156    partition_desc->loadSections(physProxy);
157
158
159    // @todo any fixup code over writing data in binaries on setting break
160    // events on functions should happen here.
161
162}
163
164SparcSystem::~SparcSystem()
165{
166    delete resetSymtab;
167    delete hypervisorSymtab;
168    delete openbootSymtab;
169    delete nvramSymtab;
170    delete hypervisorDescSymtab;
171    delete partitionDescSymtab;
172    delete reset;
173    delete openboot;
174    delete hypervisor;
175    delete nvram;
176    delete hypervisor_desc;
177    delete partition_desc;
178}
179
180void
181SparcSystem::serializeSymtab(CheckpointOut &cp) const
182{
183    resetSymtab->serialize("reset_symtab", cp);
184    hypervisorSymtab->serialize("hypervisor_symtab", cp);
185    openbootSymtab->serialize("openboot_symtab", cp);
186    nvramSymtab->serialize("nvram_symtab", cp);
187    hypervisorDescSymtab->serialize("hypervisor_desc_symtab", cp);
188    partitionDescSymtab->serialize("partition_desc_symtab", cp);
189}
190
191
192void
193SparcSystem::unserializeSymtab(CheckpointIn &cp)
194{
195    resetSymtab->unserialize("reset_symtab", cp);
196    hypervisorSymtab->unserialize("hypervisor_symtab", cp);
197    openbootSymtab->unserialize("openboot_symtab", cp);
198    nvramSymtab->unserialize("nvram_symtab", cp);
199    hypervisorDescSymtab->unserialize("hypervisor_desc_symtab", cp);
200    partitionDescSymtab->unserialize("partition_desc_symtab", cp);
201}
202
203SparcSystem *
204SparcSystemParams::create()
205{
206    return new SparcSystem(this);
207}
208