/branches/sparc/kernel/generic/src/main/main.c |
---|
299,7 → 299,6 |
*/ |
void main_ap(void) |
{ |
asm volatile ("sethi 0x40543, %g0"); |
/* |
* Incrementing the active CPU counter will guarantee that the |
* *_init() functions can find out that they need to |
/branches/sparc/kernel/generic/src/cpu/cpu.c |
---|
99,6 → 99,7 |
void cpu_list(void) |
{ |
unsigned int i; |
for (i = 0; i < config.cpu_count; i++) { |
if (cpus[i].active) |
cpu_print_report(&cpus[i]); |
/branches/sparc/kernel/arch/sparc64/include/cpu_family.h |
---|
File deleted |
\ No newline at end of file |
/branches/sparc/kernel/arch/sparc64/include/regdef.h |
---|
60,11 → 60,7 |
* FIREPLANE_CONFIG register on US3. |
*/ |
#define ICBUS_CONFIG_MID_SHIFT 17 |
#if defined (US) |
#define ICBUS_CONFIG_MID_MASK 0x1f |
#elif defined (US3) |
#define ICBUS_CONFIG_MID_MASK 0x3ff |
#endif |
#endif |
/branches/sparc/kernel/arch/sparc64/include/register.h |
---|
126,16 → 126,10 |
union icbus_config { |
uint64_t value; |
struct { |
#if defined (US) |
uint64_t : 34; |
unsigned pcon : 8; /**< Processor configuration. */ |
unsigned mid : 5; /**< Module (processor) ID register. */ |
unsigned pcap : 17; /**< Processor capabilities. */ |
#elif defined (US3) |
uint64_t : 37; |
unsigned mid : 10; /**< Module (processor) ID register. */ |
uint64_t : 17; |
#endif |
} __attribute__ ((packed)); |
}; |
typedef union icbus_config icbus_config_t; |
/branches/sparc/kernel/arch/sparc64/include/cpu_node.h |
---|
37,11 → 37,19 |
#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 (nodes named "cpu" or "cmp"). |
/** Finds the parent node of all the CPU nodes. |
* |
* Depending on the machine type (and possibly the OFW version), CPUs can be |
* at "/" or at "/ssm@0,0". |
* Depending on the OFW version, CPUS can be at "/" or at "/ssm@0,0". |
*/ |
static inline ofw_tree_node_t *cpus_parent(void) |
{ |
/branches/sparc/kernel/arch/sparc64/src/smp/smp.c |
---|
35,7 → 35,6 |
#include <smp/smp.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <cpu.h> |
#include <arch/cpu_family.h> |
#include <arch/cpu.h> |
#include <arch.h> |
#include <config.h> |
63,47 → 62,41 |
ofw_tree_node_t *node; |
count_t cnt = 0; |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
cnt++; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
cnt += 2; |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
} |
} |
config.cpu_count = max(1, cnt); |
} |
/** |
* Wakes up the CPU which is represented by the "node" OFW tree node. |
* If "node" represents the current CPU, calling the function has |
* no effect. |
*/ |
static void wakeup_cpu(ofw_tree_node_t *node) |
/** Wake application processors up. */ |
void kmp(void *arg) |
{ |
ofw_tree_node_t *node; |
int i; |
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; |
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */ |
prop = ofw_tree_getprop(node, "upa-portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "cpuid"); |
prop = ofw_tree_getprop(node, PORTID_NAME); |
if (!prop || !prop->value) |
continue; |
if (!prop || prop->value == NULL) |
return; |
mid = *((uint32_t *) prop->value); |
if (CPU->arch.mid == mid) |
return; |
if (CPU->arch.mid == mid) { |
/* |
* Skip the current CPU. |
*/ |
continue; |
} |
/* |
* Processor with ID == mid can proceed with its initialization. |
*/ |
waking_up_mid = mid; |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) |
110,28 → 103,7 |
printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n", |
__func__, mid); |
} |
/** Wake application processors up. */ |
void kmp(void *arg) |
{ |
ofw_tree_node_t *node; |
int i; |
printf("\nGoing to wake CPUs up.\n"); |
if (is_us() || is_us_iii()) { |
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++) |
wakeup_cpu(node); |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
wakeup_cpu(ofw_tree_find_child(node, "cpu@0")); |
wakeup_cpu(ofw_tree_find_child(node, "cpu@1")); |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
} |
} |
} |
/** @} |
*/ |
/branches/sparc/kernel/arch/sparc64/src/cpu/cpu.c |
---|
32,7 → 32,6 |
/** @file |
*/ |
#include <arch/cpu_family.h> |
#include <cpu.h> |
#include <arch.h> |
#include <genarch/ofw/ofw_tree.h> |
40,38 → 39,6 |
#include <print.h> |
#include <arch/cpu_node.h> |
/** |
* Finds out the clock frequency of the current CPU. |
* |
* @param node node representing the current CPU in the OFW tree |
* @return clock frequency if "node" is the current CPU and no error |
* occurs, -1 if "node" is not the current CPU or on error |
*/ |
static int find_cpu_frequency(ofw_tree_node_t *node) |
{ |
ofw_tree_property_t *prop; |
uint32_t mid; |
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */ |
prop = ofw_tree_getprop(node, "upa-portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "cpuid"); |
if (prop && prop->value) { |
mid = *((uint32_t *) prop->value); |
if (mid == CPU->arch.mid) { |
prop = ofw_tree_getprop(node, "clock-frequency"); |
if (prop && prop->value) { |
return *((uint32_t *) prop->value); |
} |
} |
} |
return -1; |
} |
/** Perform sparc64 specific initialization of the processor structure for the |
* current processor. |
*/ |
78,6 → 45,7 |
void cpu_arch_init(void) |
{ |
ofw_tree_node_t *node; |
uint32_t mid; |
uint32_t clock_frequency = 0; |
icbus_config_t icbus_config; |
87,26 → 55,22 |
/* |
* Detect processor frequency. |
*/ |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
int f = find_cpu_frequency(node); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
ofw_tree_property_t *prop; |
prop = ofw_tree_getprop(node, PORTID_NAME); |
if (prop && prop->value) { |
mid = *((uint32_t *) prop->value); |
if (mid == CPU->arch.mid) { |
prop = ofw_tree_getprop(node, |
"clock-frequency"); |
if (prop && prop->value) |
clock_frequency = *((uint32_t *) |
prop->value); |
} |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
int f; |
f = find_cpu_frequency(ofw_tree_find_child(node, "cpu@0")); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
f = find_cpu_frequency(ofw_tree_find_child(node, "cpu@1")); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
} |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
CPU->arch.clock_frequency = clock_frequency; |
/branches/sparc/kernel/genarch/include/ofw/ofw_tree.h |
---|
168,7 → 168,6 |
extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name); |
extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *device_type); |
extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *device_type); |
extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name); |
extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle); |
extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uintptr_t *pa); |
/branches/sparc/kernel/genarch/src/ofw/ofw_tree.c |
---|
202,29 → 202,6 |
} |
/** Lookup first peer of given name. |
* |
* @param node Node whose peer is being looked up. |
* @param name Name of the child being looked up. |
* |
* @return NULL if there is no such peer or pointer to the matching peer node. |
*/ |
ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name) |
{ |
ofw_tree_node_t *cur; |
ofw_tree_property_t *prop; |
for (cur = node->peer; cur; cur = cur->peer) { |
prop = ofw_tree_getprop(cur, "name"); |
if (!prop || !prop->value) |
continue; |
if (strcmp(prop->value, name) == 0) |
return cur; |
} |
return NULL; |
} |
/** Lookup OpenFirmware node by its path. |
* |
* @param path Path to the node. |
/branches/sparc/uspace/srv/kbd/genarch/src/nofb.c |
---|
36,7 → 36,6 |
*/ |
#include <genarch/nofb.h> |
#include <stdio.h> // DELETE!!! |
#define KEY_F1 0x504f1bL |
#define KEY_F2 0x514f1bL |
179,7 → 178,6 |
buf = count = 0; |
return 1; |
} |
return 1; |
} |
/branches/sparc/uspace/srv/kbd/arch/sparc64/src/sgcn.c |
---|
67,6 → 67,18 |
/** offset within the SGCN buffer of the input buffer write pointer */ |
uint32_t in_wrptr; |
/** offset within the SGCN buffer of the output buffer start */ |
uint32_t out_begin; |
/** offset within the SGCN buffer of the output buffer end */ |
uint32_t out_end; |
/** offset within the SGCN buffer of the output buffer read pointer */ |
uint32_t out_rdptr; |
/** offset within the SGCN buffer of the output buffer write pointer */ |
uint32_t out_wrptr; |
} __attribute__ ((packed)) sgcn_buffer_header_t; |
/* |
113,6 → 125,8 |
0, (void *) 0); |
} |
/** |
* Handler of the "key pressed" event. Reads codes of all the pressed keys from |
* the buffer. |
139,6 → 153,7 |
if (c == '\r') { |
c = '\n'; |
} |
//keybuffer_push(&keybuffer, c); |
kbd_process_no_fb(&keybuffer, c); |
} |
} |
/branches/sparc/uspace/srv/fb/serial_console.c |
---|
File deleted |
\ No newline at end of file |
/branches/sparc/uspace/srv/fb/serial_console.h |
---|
File deleted |
\ No newline at end of file |
/branches/sparc/uspace/srv/fb/sgcn.c |
---|
44,12 → 44,13 |
#include <stdio.h> |
#include <ddi.h> |
#include "serial_console.h" |
#include "sgcn.h" |
#define WIDTH 80 |
#define HEIGHT 24 |
#define MAX_CONTROL 20 |
/** |
* Virtual address mapped to SRAM. |
*/ |
72,8 → 73,20 |
char magic[4]; |
/** we don't need this */ |
char unused[24]; |
char unused[8]; |
/** offset within the SGCN buffer of the input buffer start */ |
uint32_t in_begin; |
/** offset within the SGCN buffer of the input buffer end */ |
uint32_t in_end; |
/** offset within the SGCN buffer of the input buffer read pointer */ |
uint32_t in_rdptr; |
/** offset within the SGCN buffer of the input buffer write pointer */ |
uint32_t in_wrptr; |
/** offset within the SGCN buffer of the output buffer start */ |
uint32_t out_begin; |
87,6 → 100,8 |
uint32_t out_wrptr; |
} __attribute__ ((packed)) sgcn_buffer_header_t; |
// TODO it is suggested to extract the common parts of this file and the msim.c file |
// into a separate file and place that file to the genarch directory |
/* |
* Returns a pointer to the object of a given type which is placed at the given |
117,6 → 132,57 |
*out_wrptr_ptr = new_wrptr; |
} |
static void sgcn_puts(char *str) |
{ |
while (*str) |
sgcn_putc(*(str++)); |
} |
static void sgcn_goto(const unsigned int row, const unsigned int col) |
{ |
if ((row > HEIGHT) || (col > WIDTH)) |
return; |
char control[20]; |
snprintf(control, 20, "\033[%u;%uf", row + 1, col + 1); |
sgcn_puts(control); |
} |
static void sgcn_clrscr(void) |
{ |
sgcn_puts("\033[2J"); |
} |
static void sgcn_scroll(int i) |
{ |
if (i > 0) { |
sgcn_goto(HEIGHT - 1, 0); |
while (i--) |
sgcn_puts("\033D"); |
} else if (i < 0) { |
sgcn_goto(0, 0); |
while (i++) |
sgcn_puts("\033M"); |
} |
} |
static void sgcn_set_style(const unsigned int mode) |
{ |
char control[MAX_CONTROL]; |
snprintf(control, MAX_CONTROL, "\033[%um", mode); |
sgcn_puts(control); |
} |
static void sgcn_cursor_disable(void) |
{ |
sgcn_puts("\033[?25l"); |
} |
static void sgcn_cursor_enable(void) |
{ |
sgcn_puts("\033[?25h"); |
} |
static void sgcn_client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
int retval; |
141,9 → 207,9 |
/* Clear the terminal, set scrolling region |
to 0 - 24 lines */ |
serial_clrscr(); |
serial_goto(0, 0); |
serial_puts("\033[0;24r"); |
sgcn_clrscr(); |
sgcn_goto(0, 0); |
sgcn_puts("\033[0;24r"); |
while (true) { |
callid = async_get_call(&call); |
157,7 → 223,7 |
newrow = IPC_GET_ARG2(call); |
newcol = IPC_GET_ARG3(call); |
if ((lastcol != newcol) || (lastrow != newrow)) |
serial_goto(newrow, newcol); |
sgcn_goto(newrow, newcol); |
lastcol = newcol + 1; |
lastrow = newrow; |
sgcn_putc(c); |
166,7 → 232,7 |
case FB_CURSOR_GOTO: |
newrow = IPC_GET_ARG1(call); |
newcol = IPC_GET_ARG2(call); |
serial_goto(newrow, newcol); |
sgcn_goto(newrow, newcol); |
lastrow = newrow; |
lastcol = newcol; |
retval = 0; |
175,7 → 241,7 |
ipc_answer_2(callid, EOK, HEIGHT, WIDTH); |
continue; |
case FB_CLEAR: |
serial_clrscr(); |
sgcn_clrscr(); |
retval = 0; |
break; |
case FB_SET_STYLE: |
182,9 → 248,9 |
fgcolor = IPC_GET_ARG1(call); |
bgcolor = IPC_GET_ARG2(call); |
if (fgcolor < bgcolor) |
serial_set_style(0); |
sgcn_set_style(0); |
else |
serial_set_style(7); |
sgcn_set_style(7); |
retval = 0; |
break; |
case FB_SCROLL: |
193,15 → 259,15 |
retval = EINVAL; |
break; |
} |
serial_scroll(i); |
serial_goto(lastrow, lastcol); |
sgcn_scroll(i); |
sgcn_goto(lastrow, lastcol); |
retval = 0; |
break; |
case FB_CURSOR_VISIBILITY: |
if(IPC_GET_ARG1(call)) |
serial_cursor_enable(); |
sgcn_cursor_enable(); |
else |
serial_cursor_disable(); |
sgcn_cursor_disable(); |
retval = 0; |
break; |
default: |
225,8 → 291,6 |
result); |
} |
serial_console_init(sgcn_putc, WIDTH, HEIGHT); |
sram_buffer_offset = sysinfo_value("sram.buffer.offset"); |
async_set_client_connection(sgcn_client_connection); |
/branches/sparc/uspace/srv/fb/Makefile |
---|
59,13 → 59,11 |
CFLAGS += -DEGA_ENABLED |
endif |
ifeq ($(ARCH), mips32) |
SOURCES += msim.c \ |
serial_console.c |
SOURCES += msim.c |
CFLAGS += -DMSIM_ENABLED -DFB_INVERT_ENDIAN |
endif |
ifeq ($(ARCH), sparc64) |
SOURCES += sgcn.c \ |
serial_console.c |
SOURCES += sgcn.c |
CFLAGS += -DSGCN_ENABLED |
endif |
/branches/sparc/uspace/srv/fb/msim.c |
---|
49,7 → 49,6 |
#include <align.h> |
#include <ddi.h> |
#include "serial_console.h" |
#include "msim.h" |
#define WIDTH 80 |
67,6 → 66,57 |
*virt_addr = c; |
} |
static void msim_puts(char *str) |
{ |
while (*str) |
*virt_addr = *(str++); |
} |
static void msim_clrscr(void) |
{ |
msim_puts("\033[2J"); |
} |
static void msim_goto(const unsigned int row, const unsigned int col) |
{ |
if ((row > HEIGHT) || (col > WIDTH)) |
return; |
char control[MAX_CONTROL]; |
snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1); |
msim_puts(control); |
} |
static void msim_set_style(const unsigned int mode) |
{ |
char control[MAX_CONTROL]; |
snprintf(control, MAX_CONTROL, "\033[%um", mode); |
msim_puts(control); |
} |
static void msim_cursor_disable(void) |
{ |
msim_puts("\033[?25l"); |
} |
static void msim_cursor_enable(void) |
{ |
msim_puts("\033[?25h"); |
} |
static void msim_scroll(int i) |
{ |
if (i > 0) { |
msim_goto(HEIGHT - 1, 0); |
while (i--) |
msim_puts("\033D"); |
} else if (i < 0) { |
msim_goto(0, 0); |
while (i++) |
msim_puts("\033M"); |
} |
} |
static void msim_client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
int retval; |
91,9 → 141,9 |
/* Clear the terminal, set scrolling region |
to 0 - 25 lines */ |
serial_clrscr(); |
serial_goto(0, 0); |
serial_puts("\033[0;25r"); |
msim_clrscr(); |
msim_goto(0, 0); |
msim_puts("\033[0;25r"); |
while (true) { |
callid = async_get_call(&call); |
107,7 → 157,7 |
newrow = IPC_GET_ARG2(call); |
newcol = IPC_GET_ARG3(call); |
if ((lastcol != newcol) || (lastrow != newrow)) |
serial_goto(newrow, newcol); |
msim_goto(newrow, newcol); |
lastcol = newcol + 1; |
lastrow = newrow; |
msim_putc(c); |
116,7 → 166,7 |
case FB_CURSOR_GOTO: |
newrow = IPC_GET_ARG1(call); |
newcol = IPC_GET_ARG2(call); |
serial_goto(newrow, newcol); |
msim_goto(newrow, newcol); |
lastrow = newrow; |
lastcol = newcol; |
retval = 0; |
125,7 → 175,7 |
ipc_answer_2(callid, EOK, HEIGHT, WIDTH); |
continue; |
case FB_CLEAR: |
serial_clrscr(); |
msim_clrscr(); |
retval = 0; |
break; |
case FB_SET_STYLE: |
132,9 → 182,9 |
fgcolor = IPC_GET_ARG1(call); |
bgcolor = IPC_GET_ARG2(call); |
if (fgcolor < bgcolor) |
serial_set_style(0); |
msim_set_style(0); |
else |
serial_set_style(7); |
msim_set_style(7); |
retval = 0; |
break; |
case FB_SCROLL: |
143,15 → 193,15 |
retval = EINVAL; |
break; |
} |
serial_scroll(i); |
serial_goto(lastrow, lastcol); |
msim_scroll(i); |
msim_goto(lastrow, lastcol); |
retval = 0; |
break; |
case FB_CURSOR_VISIBILITY: |
if(IPC_GET_ARG1(call)) |
serial_cursor_enable(); |
msim_cursor_enable(); |
else |
serial_cursor_disable(); |
msim_cursor_disable(); |
retval = 0; |
break; |
default: |
168,8 → 218,6 |
physmem_map(phys_addr, virt_addr, 1, AS_AREA_READ | AS_AREA_WRITE); |
serial_console_init(msim_putc, WIDTH, HEIGHT); |
async_set_client_connection(msim_client_connection); |
return 0; |
} |
/branches/sparc/uspace/app/init/init.c |
---|
114,11 → 114,6 |
spawn("/app/bdsh"); |
while (1) |
{ |
putchar(getchar()); |
} |
return 0; |
} |
/branches/sparc/boot/arch/sparc64/loader/asm.S |
---|
110,18 → 110,28 |
/* |
* US3 processors have a write-invalidate cache, so explicitly |
* invalidating it is not required. Whether to invalidate I-cache |
* or not is decided according to the value of the global |
* "subarchitecture" variable (set in the bootstrap). |
* or not is decided according to the value of the ver.impl bits |
* in the Version register. |
*/ |
set subarchitecture, %g2 |
ldub [%g2], %g2 |
cmp %g2, 3 |
be 1f |
! the lowest/greatest value of ver.impl for US3 |
#define FIRST_US3_CPU 0x14 |
#define LAST_US3_CPU 0x19 |
rdpr %ver, %g2 ! autodetect CPU using the Version register |
sllx %g2, 16, %g2 ! extract ver.impl bits |
srlx %g2, 48, %g2 |
addcc %g2, -FIRST_US3_CPU, %g0 ! flush if ver.impl < FISRT_US3_CPU |
bl 0f |
nop |
addcc %g2, -LAST_US3_CPU, %g0 ! flush if ver.impl > LAST_US3_CPU |
bg 0f |
nop |
ba 1f |
nop |
0: |
call icache_flush |
nop |
1: |
membar #StoreStore |
/* |
/branches/sparc/boot/arch/sparc64/loader/main.c |
---|
39,10 → 39,6 |
#include <string.h> |
bootinfo_t bootinfo; |
/** UltraSPARC subarchitecture - 1 for US, 3 for US3 */ |
uint8_t subarchitecture; |
component_t components[COMPONENTS]; |
char *release = RELEASE; |
67,21 → 63,6 |
release, revision, timestamp); |
} |
#define FIRST_US3_CPU 0x14 |
#define LAST_US3_CPU 0x19 |
static void detect_subarchitecture(void) |
{ |
uint64_t v; |
asm volatile ("rdpr %%ver, %0\n" : "=r" (v)); |
v = (v << 16) >> 48; |
if ((v >= FIRST_US3_CPU) && (v <= LAST_US3_CPU)) { |
subarchitecture = SUBARCH_US3; |
} else if (v < FIRST_US3_CPU) { |
subarchitecture = SUBARCH_US; |
} |
} |
void bootstrap(void) |
{ |
void *base = (void *) KERNEL_VIRTUAL_ADDRESS; |
91,7 → 72,6 |
version_print(); |
detect_subarchitecture(); |
init_components(components); |
if (!ofw_get_physmem_start(&bootinfo.physmem_start)) { |
/branches/sparc/boot/arch/sparc64/loader/ofwarch.c |
---|
40,8 → 40,6 |
#include "main.h" |
#include "asm.h" |
extern uint8_t subarchitecture; |
void write(const char *str, const int len) |
{ |
int i; |
58,28 → 56,46 |
return flag != -1; |
} |
static int wake_cpus_in_node(phandle child, uint64_t current_mid) |
int ofw_cpu(void) |
{ |
int cpus; |
char type_name[BUF_SIZE]; |
phandle node; |
phandle ssm; |
for (cpus = 0; child != 0 && child != -1; |
child = ofw_get_peer_node(child), cpus++) { |
if (ofw_get_property(child, "device_type", type_name, |
ssm = ofw_find_device("/ssm@0,0"); |
if (ssm == -1) { |
node = ofw_get_child_node(ofw_root); |
} else { |
node = ofw_get_child_node(ssm); |
} |
if (node == 0 || node == -1) { |
printf("Could not find any child nodes of the root node.\n"); |
return 0; |
} |
uint64_t current_mid; |
asm volatile ("ldxa [%1] %2, %0\n" |
: "=r" (current_mid) |
: "r" (0), "i" (ASI_ICBUS_CONFIG)); |
current_mid >>= ICBUS_CONFIG_MID_SHIFT; |
current_mid &= ICBUS_CONFIG_MID_MASK; |
int cpus; |
for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node), |
cpus++) { |
if (ofw_get_property(node, "device_type", type_name, |
sizeof(type_name)) > 0) { |
if (strcmp(type_name, "cpu") == 0) { |
uint32_t mid; |
/* |
* "upa-portid" for US, "portid" for US-III, |
* "cpuid" for US-IV* |
*/ |
/* "upa-portid" for US, "portid" for US-III */ |
if (ofw_get_property( |
child, "upa-portid", |
node, "upa-portid", |
&mid, sizeof(mid)) <= 0 |
&& ofw_get_property(child, "portid", |
&mid, sizeof(mid)) <= 0 |
&& ofw_get_property(child, "cpuid", |
&& ofw_get_property(node, "portid", |
&mid, sizeof(mid)) <= 0) |
continue; |
87,9 → 103,8 |
/* |
* Start secondary processor. |
*/ |
printf("Starting CPU: %d.\n", mid); |
(void) ofw_call("SUNW,start-cpu", 3, 1, |
NULL, child, KERNEL_VIRTUAL_ADDRESS, |
NULL, node, KERNEL_VIRTUAL_ADDRESS, |
bootinfo.physmem_start | |
AP_PROCESSOR); |
} |
100,58 → 115,6 |
return cpus; |
} |
int ofw_cpu(void) |
{ |
int cpus; |
phandle node; |
phandle subnode; |
phandle ssm; |
phandle cmp; |
char name[BUF_SIZE]; |
/* get the current CPU MID */ |
uint64_t current_mid; |
asm volatile ("ldxa [%1] %2, %0\n" |
: "=r" (current_mid) |
: "r" (0), "i" (ASI_ICBUS_CONFIG)); |
current_mid >>= ICBUS_CONFIG_MID_SHIFT; |
if (subarchitecture == SUBARCH_US) { |
current_mid &= ICBUS_CONFIG_MID_MASK_US; |
} else if (subarchitecture == SUBARCH_US3) { |
current_mid &= ICBUS_CONFIG_MID_MASK_US3; |
} else { |
printf("MID format unknown for this subarchitecture."); |
return 0; |
} |
/* wake up CPUs */ |
ssm = ofw_find_device("/ssm@0,0"); |
if (ssm == -1) { |
node = ofw_get_child_node(ofw_root); |
cpus = wake_cpus_in_node(node, current_mid); |
} else { |
node = ofw_get_child_node(ssm); |
cpus = wake_cpus_in_node(node, current_mid); |
while (node != 0 && node != -1) { |
if (ofw_get_property(node, "name", name, |
sizeof(name)) > 0) { |
if (strcmp(name, "cmp") == 0) { |
printf("nasel jsem dalsi CPU"); |
subnode = ofw_get_child_node(node); |
cpus += wake_cpus_in_node(subnode, |
current_mid); |
} |
} |
node = ofw_get_peer_node(node); |
} |
} |
return cpus; |
} |
/** Get physical memory starting address. |
* |
* @param start Pointer to variable where the physical memory starting |
/branches/sparc/boot/arch/sparc64/loader/register.h |
---|
35,7 → 35,6 |
#define ASI_ICBUS_CONFIG 0x4a |
#define ICBUS_CONFIG_MID_SHIFT 17 |
#define ICBUS_CONFIG_MID_MASK_US 0x1f |
#define ICBUS_CONFIG_MID_MASK_US3 0x3ff |
#define ICBUS_CONFIG_MID_MASK 0x1f |
#endif |
/branches/sparc/boot/arch/sparc64/loader/main.h |
---|
41,9 → 41,6 |
#define BSP_PROCESSOR 1 |
#define AP_PROCESSOR 0 |
#define SUBARCH_US 1 |
#define SUBARCH_US3 3 |
typedef struct { |
void *addr; |
uint32_t size; |
/branches/sparc/boot/genarch/ofw_tree.c |
---|
121,6 → 121,7 |
memcpy(current_node->da_name, &path[i], len); |
current_node->da_name[len] = '\0'; |
/* |
* Recursively process the potential child node. |
*/ |
/branches/sparc/usiii.simics |
---|
11,7 → 11,7 |
if not defined rtc_time {$rtc_time = "2002-06-02 17:00:00 UTC"} |
if not defined num_cpus {$num_cpus = 1} |
if not defined megs_per_cpu {$megs_per_cpu = 256} |
if not defined cpu_class {$cpu_class = "ultrasparc-iv"} |
if not defined cpu_class {$cpu_class = "ultrasparc-iii"} |
### |
/branches/sparc/usii.simics |
---|
36,7 → 36,7 |
if not defined mac_address {$mac_address = "10:10:10:10:10:12"} |
if not defined disk_size {$disk_size = 2128486400} |
if not defined rtc_time {$rtc_time = "2002-06-02 13:00:00 UTC"} |
if not defined num_cpus {$num_cpus = 5} |
if not defined num_cpus {$num_cpus = 3} |
if not defined memory_megs {$memory_megs = 256} |
if not defined save_slot2 {$save_slot2 = "no"} |