Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3581 → Rev 3582

/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 = 3}
if not defined num_cpus {$num_cpus = 5}
if not defined memory_megs {$memory_megs = 256}
if not defined save_slot2 {$save_slot2 = "no"}
 
/branches/sparc/kernel/genarch/include/ofw/ofw_tree.h
168,6 → 168,7
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,6 → 202,29
}
 
 
/** 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/kernel/generic/src/main/main.c
299,6 → 299,7
*/
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,7 → 99,6
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_node.h
37,19 → 37,11
 
#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.
/** Finds the parent node of all the CPU nodes (nodes named "cpu" or "cmp").
*
* Depending on the OFW version, CPUS can be at "/" or at "/ssm@0,0".
* Depending on the machine type (and possibly 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/include/regdef.h
60,7 → 60,11
* 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,10 → 126,16
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_family.h
0,0 → 1,82
/*
* Copyright (c) 2008 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_FAMILY_H_
#define KERN_sparc64_CPU_FAMILY_H_
 
#include <arch.h>
#include <cpu.h>
#include <arch/register.h>
#include <arch/asm.h>
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US family
*/
static inline bool is_us(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCI) || (impl == IMPL_ULTRASPARCII) ||
(impl == IMPL_ULTRASPARCII_I) || (impl == IMPL_ULTRASPARCII_E);
}
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US-III subfamily
*/
static inline bool is_us_iii(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCIII) ||
(impl == IMPL_ULTRASPARCIII_PLUS) ||
(impl == IMPL_ULTRASPARCIII_I);
}
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US-IV subfamily
*/
static inline bool is_us_iv(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCIV) || (impl == IMPL_ULTRASPARCIV_PLUS);
}
#endif
 
/** @}
*/
/branches/sparc/kernel/arch/sparc64/src/smp/smp.c
35,6 → 35,7
#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>
62,15 → 63,54
ofw_tree_node_t *node;
count_t cnt = 0;
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
while (node) {
cnt++;
node = ofw_tree_find_peer_by_device_type(node, "cpu");
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)
{
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");
if (!prop || prop->value == NULL)
return;
mid = *((uint32_t *) prop->value);
if (CPU->arch.mid == mid)
return;
 
waking_up_mid = mid;
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT)
printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n",
__func__, mid);
}
 
/** Wake application processors up. */
void kmp(void *arg)
{
77,31 → 117,19
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;
prop = ofw_tree_getprop(node, PORTID_NAME);
if (!prop || !prop->value)
continue;
mid = *((uint32_t *) prop->value);
if (CPU->arch.mid == mid) {
/*
* Skip the current CPU.
*/
continue;
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");
}
 
/*
* 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)
printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n",
__func__, mid);
}
}
 
/branches/sparc/kernel/arch/sparc64/src/cpu/cpu.c
32,6 → 32,7
/** @file
*/
 
#include <arch/cpu_family.h>
#include <cpu.h>
#include <arch.h>
#include <genarch/ofw/ofw_tree.h>
39,6 → 40,38
#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.
*/
45,7 → 78,6
void cpu_arch_init(void)
{
ofw_tree_node_t *node;
uint32_t mid;
uint32_t clock_frequency = 0;
icbus_config_t icbus_config;
55,24 → 87,28
/*
* Detect processor frequency.
*/
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
while (node) {
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);
}
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");
}
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) {
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");
}
}
 
CPU->arch.clock_frequency = clock_frequency;
tick_init();
}
/branches/sparc/uspace/app/init/init.c
114,6 → 114,11
spawn("/app/bdsh");
while (1)
{
putchar(getchar());
}
return 0;
}
 
/branches/sparc/uspace/srv/kbd/genarch/src/nofb.c
36,6 → 36,7
*/
 
#include <genarch/nofb.h>
#include <stdio.h> // DELETE!!!
 
#define KEY_F1 0x504f1bL
#define KEY_F2 0x514f1bL
178,6 → 179,7
buf = count = 0;
return 1;
}
 
return 1;
}
 
/branches/sparc/uspace/srv/kbd/arch/sparc64/src/sgcn.c
67,18 → 67,6
/** 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;
 
/*
125,8 → 113,6
0, (void *) 0);
}
 
 
 
/**
* Handler of the "key pressed" event. Reads codes of all the pressed keys from
* the buffer.
153,7 → 139,6
if (c == '\r') {
c = '\n';
}
//keybuffer_push(&keybuffer, c);
kbd_process_no_fb(&keybuffer, c);
}
}
/branches/sparc/uspace/srv/fb/serial_console.c
0,0 → 1,110
/*
* Copyright (c) 2006 Ondrej Palkovsky
* Copyright (c) 2008 Martin Decky
* Copyright (c) 2008 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.
*/
 
/**
* @defgroup serial Serial console
* @brief Serial console services (putc, puts, clear screen, cursor goto,...).*
* @{
*/
 
/** @file
*/
 
#include <stdio.h>
 
#include "serial_console.h"
 
#define MAX_CONTROL 20
 
static uint32_t width;
static uint32_t height;
static putc_function_t putc_function;
 
void serial_puts(char *str)
{
while (*str)
putc_function(*(str++));
}
 
void serial_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);
serial_puts(control);
}
 
void serial_clrscr(void)
{
serial_puts("\033[2J");
}
 
void serial_scroll(int i)
{
if (i > 0) {
serial_goto(height - 1, 0);
while (i--)
serial_puts("\033D");
} else if (i < 0) {
serial_goto(0, 0);
while (i++)
serial_puts("\033M");
}
}
 
void serial_set_style(const unsigned int mode)
{
char control[MAX_CONTROL];
snprintf(control, MAX_CONTROL, "\033[%um", mode);
serial_puts(control);
}
 
void serial_cursor_disable(void)
{
serial_puts("\033[?25l");
}
 
void serial_cursor_enable(void)
{
serial_puts("\033[?25h");
}
 
void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
{
width = w;
height = h;
putc_function = putc_fn;
}
 
/**
* @}
*/
/branches/sparc/uspace/srv/fb/msim.c
49,6 → 49,7
#include <align.h>
#include <ddi.h>
 
#include "serial_console.h"
#include "msim.h"
 
#define WIDTH 80
66,57 → 67,6
*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;
141,9 → 91,9
/* Clear the terminal, set scrolling region
to 0 - 25 lines */
msim_clrscr();
msim_goto(0, 0);
msim_puts("\033[0;25r");
serial_clrscr();
serial_goto(0, 0);
serial_puts("\033[0;25r");
while (true) {
callid = async_get_call(&call);
157,7 → 107,7
newrow = IPC_GET_ARG2(call);
newcol = IPC_GET_ARG3(call);
if ((lastcol != newcol) || (lastrow != newrow))
msim_goto(newrow, newcol);
serial_goto(newrow, newcol);
lastcol = newcol + 1;
lastrow = newrow;
msim_putc(c);
166,7 → 116,7
case FB_CURSOR_GOTO:
newrow = IPC_GET_ARG1(call);
newcol = IPC_GET_ARG2(call);
msim_goto(newrow, newcol);
serial_goto(newrow, newcol);
lastrow = newrow;
lastcol = newcol;
retval = 0;
175,7 → 125,7
ipc_answer_2(callid, EOK, HEIGHT, WIDTH);
continue;
case FB_CLEAR:
msim_clrscr();
serial_clrscr();
retval = 0;
break;
case FB_SET_STYLE:
182,9 → 132,9
fgcolor = IPC_GET_ARG1(call);
bgcolor = IPC_GET_ARG2(call);
if (fgcolor < bgcolor)
msim_set_style(0);
serial_set_style(0);
else
msim_set_style(7);
serial_set_style(7);
retval = 0;
break;
case FB_SCROLL:
193,15 → 143,15
retval = EINVAL;
break;
}
msim_scroll(i);
msim_goto(lastrow, lastcol);
serial_scroll(i);
serial_goto(lastrow, lastcol);
retval = 0;
break;
case FB_CURSOR_VISIBILITY:
if(IPC_GET_ARG1(call))
msim_cursor_enable();
serial_cursor_enable();
else
msim_cursor_disable();
serial_cursor_disable();
retval = 0;
break;
default:
218,6 → 168,8
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/srv/fb/serial_console.h
0,0 → 1,52
/*
* Copyright (c) 2008 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.
*/
 
/**
* @defgroup serial Serial console
* @brief Serial console services (putc, puts, clear screen, cursor goto,...).*
* @{
*/
 
/** @file
*/
 
#ifndef FB_SERIAL_CONSOLE_H_
#define FB_SERIAL_CONSOLE_H_
 
typedef void (*putc_function_t)(char);
 
void serial_puts(char *str);
void serial_goto(const unsigned int row, const unsigned int col);
void serial_clrscr(void);
void serial_scroll(int i);
void serial_set_style(const unsigned int mode);
void serial_cursor_disable(void);
void serial_cursor_enable(void);
void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h);
 
#endif
/branches/sparc/uspace/srv/fb/sgcn.c
44,13 → 44,12
#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.
*/
73,19 → 72,7
char magic[4];
/** we don't need this */
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;
char unused[24];
 
/** offset within the SGCN buffer of the output buffer start */
uint32_t out_begin;
100,8 → 87,6
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
132,57 → 117,6
*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;
207,9 → 141,9
/* Clear the terminal, set scrolling region
to 0 - 24 lines */
sgcn_clrscr();
sgcn_goto(0, 0);
sgcn_puts("\033[0;24r");
serial_clrscr();
serial_goto(0, 0);
serial_puts("\033[0;24r");
while (true) {
callid = async_get_call(&call);
223,7 → 157,7
newrow = IPC_GET_ARG2(call);
newcol = IPC_GET_ARG3(call);
if ((lastcol != newcol) || (lastrow != newrow))
sgcn_goto(newrow, newcol);
serial_goto(newrow, newcol);
lastcol = newcol + 1;
lastrow = newrow;
sgcn_putc(c);
232,7 → 166,7
case FB_CURSOR_GOTO:
newrow = IPC_GET_ARG1(call);
newcol = IPC_GET_ARG2(call);
sgcn_goto(newrow, newcol);
serial_goto(newrow, newcol);
lastrow = newrow;
lastcol = newcol;
retval = 0;
241,7 → 175,7
ipc_answer_2(callid, EOK, HEIGHT, WIDTH);
continue;
case FB_CLEAR:
sgcn_clrscr();
serial_clrscr();
retval = 0;
break;
case FB_SET_STYLE:
248,9 → 182,9
fgcolor = IPC_GET_ARG1(call);
bgcolor = IPC_GET_ARG2(call);
if (fgcolor < bgcolor)
sgcn_set_style(0);
serial_set_style(0);
else
sgcn_set_style(7);
serial_set_style(7);
retval = 0;
break;
case FB_SCROLL:
259,15 → 193,15
retval = EINVAL;
break;
}
sgcn_scroll(i);
sgcn_goto(lastrow, lastcol);
serial_scroll(i);
serial_goto(lastrow, lastcol);
retval = 0;
break;
case FB_CURSOR_VISIBILITY:
if(IPC_GET_ARG1(call))
sgcn_cursor_enable();
serial_cursor_enable();
else
sgcn_cursor_disable();
serial_cursor_disable();
retval = 0;
break;
default:
291,6 → 225,8
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,11 → 59,13
CFLAGS += -DEGA_ENABLED
endif
ifeq ($(ARCH), mips32)
SOURCES += msim.c
SOURCES += msim.c \
serial_console.c
CFLAGS += -DMSIM_ENABLED -DFB_INVERT_ENDIAN
endif
ifeq ($(ARCH), sparc64)
SOURCES += sgcn.c
SOURCES += sgcn.c \
serial_console.c
CFLAGS += -DSGCN_ENABLED
endif
 
/branches/sparc/boot/genarch/ofw_tree.c
121,7 → 121,6
memcpy(current_node->da_name, &path[i], len);
current_node->da_name[len] = '\0';
/*
* Recursively process the potential child node.
*/
/branches/sparc/boot/arch/sparc64/loader/asm.S
110,28 → 110,18
/*
* 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 ver.impl bits
* in the Version register.
* or not is decided according to the value of the global
* "subarchitecture" variable (set in the bootstrap).
*/
! 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
set subarchitecture, %g2
ldub [%g2], %g2
cmp %g2, 3
be 1f
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,6 → 39,10
#include <string.h>
 
bootinfo_t bootinfo;
 
/** UltraSPARC subarchitecture - 1 for US, 3 for US3 */
uint8_t subarchitecture;
 
component_t components[COMPONENTS];
 
char *release = RELEASE;
63,6 → 67,21
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;
72,6 → 91,7
 
version_print();
detect_subarchitecture();
init_components(components);
 
if (!ofw_get_physmem_start(&bootinfo.physmem_start)) {
/branches/sparc/boot/arch/sparc64/loader/main.h
41,6 → 41,9
#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/arch/sparc64/loader/ofwarch.c
40,6 → 40,8
#include "main.h"
#include "asm.h"
 
extern uint8_t subarchitecture;
 
void write(const char *str, const int len)
{
int i;
56,46 → 58,28
return flag != -1;
}
 
int ofw_cpu(void)
static int wake_cpus_in_node(phandle child, uint64_t current_mid)
{
int cpus;
char type_name[BUF_SIZE];
phandle node;
phandle ssm;
 
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,
for (cpus = 0; child != 0 && child != -1;
child = ofw_get_peer_node(child), cpus++) {
if (ofw_get_property(child, "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 */
/*
* "upa-portid" for US, "portid" for US-III,
* "cpuid" for US-IV*
*/
if (ofw_get_property(
node, "upa-portid",
child, "upa-portid",
&mid, sizeof(mid)) <= 0
&& ofw_get_property(node, "portid",
&& ofw_get_property(child, "portid",
&mid, sizeof(mid)) <= 0
&& ofw_get_property(child, "cpuid",
&mid, sizeof(mid)) <= 0)
continue;
103,8 → 87,9
/*
* Start secondary processor.
*/
printf("Starting CPU: %d.\n", mid);
(void) ofw_call("SUNW,start-cpu", 3, 1,
NULL, node, KERNEL_VIRTUAL_ADDRESS,
NULL, child, KERNEL_VIRTUAL_ADDRESS,
bootinfo.physmem_start |
AP_PROCESSOR);
}
115,6 → 100,58
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
33,8 → 33,9
#define PSTATE_PRIV_BIT 4
#define PSTATE_AM_BIT 8
 
#define ASI_ICBUS_CONFIG 0x4a
#define ICBUS_CONFIG_MID_SHIFT 17
#define ICBUS_CONFIG_MID_MASK 0x1f
#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
 
#endif
/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-iii"}
if not defined cpu_class {$cpu_class = "ultrasparc-iv"}
 
###