/branches/sparc/kernel/generic/src/main/main.c |
---|
192,8 → 192,6 |
/* Keep this the first thing. */ |
the_initialize(THE); |
asm("sethi 0x40100, %g0"); |
LOG(); |
version_print(); |
/branches/sparc/kernel/arch/sparc64/include/cpu_node.h |
---|
0,0 → 1,66 |
/* |
* Copyright (c) 2005 Pavel Rimsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_sparc64_CPU_NODE_H_ |
#define KERN_sparc64_CPU_NODE_H_ |
#include <genarch/ofw/ofw_tree.h> |
/* |
* Name of the CPU OFW node property, which holds the MID (processor ID). |
* US uses UPA, US3 uses Fireplane, hence the properties names are different. |
*/ |
#if defined (US) |
#define PORTID_NAME "upa-portid" |
#elif defined (US3) |
#define PORTID_NAME "portid" |
#endif |
/** Finds the parent node of all the CPU nodes. |
* |
* Depending on the OFW version, CPUS can be at "/" or at "/ssm@0,0". |
*/ |
static inline ofw_tree_node_t *cpus_parent(void) |
{ |
ofw_tree_node_t *parent; |
parent = ofw_tree_find_child(ofw_tree_lookup("/"), "ssm@0,0"); |
if (parent == NULL) |
parent = ofw_tree_lookup("/"); |
return parent; |
} |
#endif |
/** @} |
*/ |
/branches/sparc/kernel/arch/sparc64/include/mm/tte.h |
---|
50,6 → 50,7 |
#include <arch/types.h> |
// TODO find out what this means |
#define VA_TAG_PAGE_SHIFT 22 |
/** Translation Table Entry - Tag. */ |
/branches/sparc/kernel/arch/sparc64/include/mm/cache_spec.h |
---|
38,20 → 38,29 |
/* |
* The following macros are valid for the following processors: |
* |
* UltraSPARC, UltraSPARC II, UltraSPARC IIi |
* UltraSPARC, UltraSPARC II, UltraSPARC IIi, UltraSPARC III Cu |
* |
* Should we support other UltraSPARC processors, we need to make sure that |
* the macros are defined correctly for them. |
*/ |
#if defined (US) |
#define DCACHE_SIZE (16 * 1024) |
#elif defined (US3) |
#define DCACHE_SIZE (64 * 1024) |
#endif |
#define DCACHE_LINE_SIZE 32 |
#if defined (US) |
#define ICACHE_SIZE (16 * 1024) |
#define ICACHE_WAYS 2 |
#elif defined (US3) |
#define ICACHE_SIZE (32 * 1024) |
#define ICACHE_WAYS 4 |
#endif |
#define ICACHE_LINE_SIZE 32 |
#endif |
/** @} |
*/ |
*/ |
/branches/sparc/kernel/arch/sparc64/include/drivers/simics_output.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2006 Pavel Rimsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_sparc64_SIMICS_OUTPUT_H_ |
#define KERN_sparc64_SIMICS_OUTPUT_H_ |
extern void simics_output_init(void); |
#endif |
/** @} |
*/ |
/branches/sparc/kernel/arch/sparc64/Makefile.inc |
---|
114,8 → 114,10 |
arch/$(ARCH)/src/drivers/tick.c \ |
arch/$(ARCH)/src/drivers/kbd.c \ |
arch/$(ARCH)/src/drivers/scr.c \ |
arch/$(ARCH)/src/drivers/pci.c |
arch/$(ARCH)/src/drivers/pci.c \ |
arch/$(ARCH)/src/drivers/simics_output.c |
ifeq ($(CONFIG_SMP),y) |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/smp/ipi.c \ |
/branches/sparc/kernel/arch/sparc64/src/smp/smp.c |
---|
43,6 → 43,7 |
#include <synch/synch.h> |
#include <synch/waitq.h> |
#include <print.h> |
#include <arch/cpu_node.h> |
/** |
* This global variable is used to pick-up application processors |
61,7 → 62,7 |
ofw_tree_node_t *node; |
count_t cnt = 0; |
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
cnt++; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
76,12 → 77,12 |
ofw_tree_node_t *node; |
int i; |
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) { |
uint32_t mid; |
ofw_tree_property_t *prop; |
prop = ofw_tree_getprop(node, "upa-portid"); |
prop = ofw_tree_getprop(node, PORTID_NAME); |
if (!prop || !prop->value) |
continue; |
/branches/sparc/kernel/arch/sparc64/src/sparc64.c |
---|
38,6 → 38,7 |
#include <arch/trap/trap.h> |
#include <arch/console.h> |
#include <proc/thread.h> |
#include <arch/drivers/simics_output.h> |
#include <console/console.h> |
#include <arch/boot/boot.h> |
#include <arch/arch.h> |
87,7 → 88,8 |
*/ |
irq_init(1 << 11, 128); |
standalone_sparc64_console_init(); |
simics_output_init(); |
//standalone_sparc64_console_init(); |
} |
} |
/branches/sparc/kernel/arch/sparc64/src/cpu/cpu.c |
---|
37,6 → 37,7 |
#include <genarch/ofw/ofw_tree.h> |
#include <arch/drivers/tick.h> |
#include <print.h> |
#include <arch/cpu_node.h> |
/** Perform sparc64 specific initialization of the processor structure for the |
* current processor. |
54,11 → 55,11 |
/* |
* Detect processor frequency. |
*/ |
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
ofw_tree_property_t *prop; |
prop = ofw_tree_getprop(node, "upa-portid"); |
prop = ofw_tree_getprop(node, PORTID_NAME); |
if (prop && prop->value) { |
mid = *((uint32_t *) prop->value); |
if (mid == CPU->arch.mid) { |
/branches/sparc/kernel/arch/sparc64/src/drivers/simics_output.c |
---|
0,0 → 1,142 |
/* |
* Copyright (c) 2006 Pavel Rimsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** |
* @file |
* @brief Routines for writing characters directly to Simics CLI. |
* |
*/ |
#include <console/chardev.h> |
#include <console/console.h> |
#include <synch/spinlock.h> |
#include <arch/drivers/simics_output.h> |
/** maximum number of characters stored before printed */ |
#define BUFSIZE 512 |
/* %g2 will store a magic value used during initialization */ |
asm (".register %g2, #scratch"); |
/* %g3 will store the address (to be passed to Simics) of the buffer */ |
asm (".register %g3, #scratch"); |
/* lock protecting the character buffer */ |
SPINLOCK_INITIALIZE(simics_buf_lock); |
static void simics_putchar(struct chardev * cd, char c); |
/** character device operations - only writing will be supported */ |
static chardev_operations_t simics_stdout_ops = { |
.suspend = NULL, |
.resume = NULL, |
.write = simics_putchar, |
.read = NULL |
}; |
/** Simics character device */ |
chardev_t simics_stdout; |
/** |
* buffer to which output characters are stored before they're printed by Simics |
*/ |
static volatile char buffer[BUFSIZE]; |
/** Writes a single character to the Simics CLI. |
* |
* The character is not written immediately, but it is stored to the first free |
* position in the buffer, waiting for Simics' Python routine to hang it up |
* and print it. |
*/ |
static void simics_putchar(struct chardev * cd, char c) |
{ |
/* the first free position in the buffer */ |
static uint16_t current = 0; |
/* '\0' terminates a contiguous block of characters to be printed! */ |
if (c == '\0') |
return; |
/* wait till buffer is non-full and other processors aren't writing to it */ |
while (1) { |
while (buffer[current] != 0) |
; |
if (spinlock_trylock(&simics_buf_lock)) |
break; |
} |
buffer[current] = c; |
current = (current + 1) % BUFSIZE; |
membar(); |
spinlock_unlock(&simics_buf_lock); |
} |
/** Initializes the Simics output. |
* |
* Passes the address of the buffer to the Simics' Python script and |
* redirects kernel output to the Simics CLI. |
*/ |
void simics_output_init(void) |
{ |
/* all buffer positions are free at the beginning */ |
uint16_t i; |
for (i = 0; i < BUFSIZE; i++) { |
buffer[i] = '\0'; |
} |
/* |
* pass the address of the buffer to the Simics' Python script |
* - write it to the %g3 register |
* - write the magic value to the %g2 register |
* (so that the script knows that the value in %g3 is valid) |
* - loop until the value is read |
* (the script notifies us by setting %g2 to 0) |
*/ |
asm volatile ( |
"or %0, 0, %%g3\n" |
"set 0x18273645, %%g2\n" |
"0: cmp %%g2, 0\n" |
"bnz 0b\n" |
"nop" |
:: "r" (buffer) |
); |
/* redirect kernel output */ |
chardev_initialize("simics_output", &simics_stdout, &simics_stdout_ops); |
stdout = &simics_stdout; |
} |
/** @} |
*/ |
/branches/sparc/boot/genarch/ofw_tree.c |
---|
220,9 → 220,27 |
{ |
ofw_tree_node_t *root; |
#if defined (SMART_FIRMWARE) |
ofw_tree_node_t *ssm; |
#endif |
root = ofw_tree_node_alloc(); |
if (root) |
ofw_tree_node_process(root, NULL, ofw_root); |
#if defined (SMART_FIRMWARE) |
/* |
* The firmware client interface does not automatically include the |
* "ssm" node in the list of children of "/". A nasty yet working |
* solution is to explicitly stick "ssm" to the OFW tree. |
*/ |
ssm = ofw_tree_node_alloc(); |
if (ssm) { |
ofw_tree_node_process(ssm, root, ofw_find_device("/ssm@0,0")); |
ssm->peer = root->child; |
root->child = ssm; |
} |
#endif |
return root; |
} |
/branches/sparc/boot/arch/sparc64/loader/ofwarch.c |
---|
56,12 → 56,23 |
return flag != -1; |
} |
/* |
* Node among whose children the CPU nodes are located. |
*/ |
#if defined (OPEN_BOOT) |
#define CPUS_PARENT_NODE ofw_root |
#elif defined (SMART_FIRMWARE) |
#define CPUS_PARENT_NODE ofw_find_device("/ssm@0,0") |
#endif |
int ofw_cpu(void) |
{ |
char type_name[BUF_SIZE]; |
phandle node; |
node = ofw_get_child_node(ofw_root); |
node = ofw_get_child_node(CPUS_PARENT_NODE); |
if (node == 0 || node == -1) { |
printf("Could not find any child nodes of the root node.\n"); |
return 0; |
84,8 → 95,12 |
if (strcmp(type_name, "cpu") == 0) { |
uint32_t mid; |
if (ofw_get_property(node, "upa-portid", &mid, |
sizeof(mid)) <= 0) |
/* "upa-portid" for US, "portid" for US-III */ |
if (ofw_get_property( |
node, "upa-portid", |
&mid, sizeof(mid)) <= 0 |
&& ofw_get_property(node, "portid", |
&mid, sizeof(mid)) <= 0) |
continue; |
if (current_mid != mid) { |
/branches/sparc/boot/arch/ppc32/Makefile.inc |
---|
26,6 → 26,8 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
DEFS += -DSMART_FIRMWARE |
build: $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot |
/branches/sparc/boot/arch/ppc64/Makefile.inc |
---|
26,6 → 26,8 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
DEFS += -DOPEN_BOOT |
build: $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot |
35,7 → 37,7 |
-rm arch/$(ARCH)/loader/image.boot |
arch/$(ARCH)/loader/image.boot: |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)" |
clean: generic_clean |
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
/branches/sparc/usiii.simics |
---|
0,0 → 1,127 |
if not defined create_network {$create_network = "yes"} |
$disk_size = 8513945600 |
### |
if not defined hostid {$hostid = 0x80804a6c} |
if not defined freq_mhz {$freq_mhz = 75} |
if not defined mac_address {$mac_address = "10:10:10:10:10:24"} |
if not defined disk_size {$disk_size = 2128486400} |
if not defined rtc_time {$rtc_time = "2002-06-02 17:00:00 UTC"} |
if not defined num_cpus {$num_cpus = 3} |
if not defined megs_per_cpu {$megs_per_cpu = 256} |
if not defined cpu_class {$cpu_class = "ultrasparc-iii-plus"} |
### |
add-directory "%simics%/targets/serengeti/images/" |
import-pci-components |
import-std-components |
import-sun-components |
import-serengeti-components |
if $cpu_class == "ultrasparc-iii-plus" { |
$create_function = "create-serengeti-us-iii-plus-cpu-board" |
} else if $cpu_class == "ultrasparc-iii" { |
$create_function = "create-serengeti-us-iii-cpu-board" |
} else if $cpu_class == "ultrasparc-iv" { |
$create_function = "create-serengeti-us-iv-cpu-board" |
} else if $cpu_class == "ultrasparc-iv-plus" { |
$create_function = "create-serengeti-us-iv-plus-cpu-board" |
} else { |
echo "Unknown cpu_class" + $cpu_class |
exit 1 |
} |
$system = (create-serengeti-6800-chassis hostid = $hostid |
mac_address = $mac_address |
rtc_time = $rtc_time) |
$board = 0 |
$cpus_left = $num_cpus |
while $cpus_left > 0 { |
$cpus = (min 4 $cpus_left) |
$cpubrd[$board] = ($create_function num_cpus = $cpus |
cpu_frequency = $freq_mhz |
memory_megs = ($megs_per_cpu * $cpus)) |
$system.connect ("cpu-slot" + $board) $cpubrd[$board] |
$board += 1 |
$cpus_left -= 4 |
} |
unset cpus |
$pciboard = (create-serengeti-pci8-board) |
$pci_hme = (create-sun-pci-hme mac_address = $mac_address) |
$pci_glm = (create-pci-sym53c875) |
$scsi_bus = (create-std-scsi-bus) |
$scsi_disk = (create-std-scsi-disk scsi_id = 0 size = $disk_size) |
$scsi_cdrom = (create-std-scsi-cdrom scsi_id = 6) |
$console = (create-std-text-console) |
### |
$system.connect io-slot6 $pciboard |
$pciboard.connect pci-slot0 $pci_hme |
$pciboard.connect pci-slot5 $pci_glm |
$scsi_bus.connect $pci_glm |
$scsi_bus.connect $scsi_disk |
$scsi_bus.connect $scsi_cdrom |
$system.connect $console |
$machine_defined = 1 |
instantiate-components |
$eth_comp = $pci_hme |
$eth_cnt = "" |
if $create_network == "yes" { |
if not $eth_link { |
$eth_link = (new-std-ethernet-link) |
} |
$eth_link.connect $eth_comp $eth_cnt |
if not $service_node { |
$service_node = (new-std-service-node) |
local $cnt = ($service_node.add-connector 10.10.0.1) |
$service_node.connect $cnt $eth_link |
} |
} |
unset eth_comp eth_cnt |
$cdrom_path = "image.iso" |
($scsi_cdrom.get-component-object cd).insert (new-file-cdrom $cdrom_path) |
$system.set-prom-env boot-command "boot /ssm@0,0/pci@19,700000/scsi@2/disk@6,0:f" |
$system.set-prom-env auto-boot? true |
@buf = 0; |
@offset = 0; |
@register2Number = SIM_get_register_number(SIM_current_processor(), "g2"); |
@register3Number = SIM_get_register_number(SIM_current_processor(), "g3"); |
@def schedule(): |
SIM_realtime_event(100, handler, 0, 0, ''); |
@def handler(x): |
global buf |
global offset |
if (SIM_simics_is_running()): |
register2Value = SIM_read_register(SIM_current_processor(), register2Number); |
if ((buf == 0) and register2Value == 0x18273645): |
buf = SIM_read_register(SIM_current_processor(), register3Number); |
SIM_write_register(SIM_current_processor(), register2Number, 0); |
SIM_flush(); |
print buf |
elif (buf != 0): |
byte = SIM_read_phys_memory(SIM_current_processor(), buf + offset, 1); |
while byte != 0: |
SIM_putchar(byte); |
SIM_flush(); |
SIM_write_phys_memory(SIM_current_processor(), buf + offset, 0, 1); |
offset = (offset + 1) % 512; |
byte = SIM_read_phys_memory(SIM_current_processor(), buf + offset, 1); |
schedule(); |
@schedule(); |