Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3590 → Rev 3591

/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 = 2}
if not defined memory_megs {$memory_megs = 256}
if not defined save_slot2 {$save_slot2 = "no"}
 
/branches/sparc/kernel/arch/sparc64/include/mm/cache_spec.h
51,16 → 51,7
#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/mm/tlb.h
41,7 → 41,7
#define DTLB_MAX_LOCKED_ENTRIES DTLB_ENTRY_COUNT
#endif
 
/** DT16 is the only of the three DMMUs that can hold locked entries. */
/** TLB_DSMALL is the only of the three DMMUs that can hold locked entries. */
#if defined (US3)
#define DTLB_MAX_LOCKED_ENTRIES 16
#endif
74,14 → 74,14
 
/* There are more TLBs in one MMU in US3, their codes are defined here. */
#if defined (US3)
/* D-MMU: one 16-entry TLB and two 512-entry TLBs */
#define TLB_DT16 0
#define TLB_DT512_0 2
#define TLB_DT512_1 3
/* D-MMU: one small (16-entry) TLB and two big (512-entry) TLBs */
#define TLB_DSMALL 0
#define TLB_DBIG_0 2
#define TLB_DBIG_1 3
/* I-MMU: one 16-entry TLB and one 128-entry TLB */
#define TLB_IT16 0
#define TLB_IT128 2
/* I-MMU: one small (16-entry) TLB and one big TLB */
#define TLB_ISMALL 0
#define TLB_IBIG 2
#endif
 
#define TLB_DEMAP_CONTEXT_SHIFT 4
99,6 → 99,8
#include <arch/asm.h>
#include <arch/barrier.h>
#include <arch/types.h>
#include <arch/register.h>
#include <arch/cpu.h>
 
union tlb_context_reg {
uint64_t v;
230,6 → 232,50
};
typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
 
#if defined (US3)
 
/*
* Functions for determining the number of entries in TLBs. They either return
* a constant value or a value based on the CPU autodetection.
*/
 
/**
* Determine the number od entries in the DMMU's small TLB.
*/
static inline uint16_t tlb_dsmall_size(void)
{
return 16;
}
 
/**
* Determine the number od entries in each DMMU's big TLB.
*/
static inline uint16_t tlb_dbig_size(void)
{
return 512;
}
 
/**
* Determine the number od entries in the IMMU's small TLB.
*/
static inline uint16_t tlb_ismall_size(void)
{
return 16;
}
 
/**
* Determine the number od entries in the IMMU's big TLB.
*/
static inline uint16_t tlb_ibig_size(void)
{
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS)
return 512;
else
return 128;
}
 
#endif
 
/** Read MMU Primary Context Register.
*
* @return Current value of Primary Context Register.
365,7 → 411,7
 
/** Read IMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Data Access Register.
381,7 → 427,7
}
 
/** Write IMMU TLB Data Access Register.
* @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
* @param value Value to be written.
*/
398,7 → 444,7
 
/** Read DMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_DT16, TLB_DT512_0, TLB_DT512_1)
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG, TLB_DBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Data Access Register.
415,7 → 461,7
 
/** Write DMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_DT16, TLB_DT512_0, TLB_DT512_1)
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1)
* @param entry TLB Entry index.
* @param value Value to be written.
*/
432,7 → 478,7
 
/** Read IMMU TLB Tag Read Register.
*
* @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Tag Read Register.
449,7 → 495,7
 
/** Read DMMU TLB Tag Read Register.
*
* @param tlb TLB number (one of TLB_DT16, TLB_DT512_0, TLB_DT512_1)
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1)
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Tag Read Register.
/branches/sparc/kernel/arch/sparc64/include/mm/cache.h
38,15 → 38,6
#include <mm/page.h>
#include <mm/frame.h>
 
#define dcache_flush_page(p) \
dcache_flush_color(PAGE_COLOR((p)))
#define dcache_flush_frame(p, f) \
dcache_flush_tag(PAGE_COLOR((p)), ADDR2PFN((f)));
 
extern void dcache_flush(void);
extern void dcache_flush_color(int c);
extern void dcache_flush_tag(int c, pfn_t tag);
 
#endif
 
/** @}
/branches/sparc/kernel/arch/sparc64/include/register.h
133,7 → 133,7
unsigned pcap : 17; /**< Processor capabilities. */
#elif defined (US3)
uint64_t : 37;
unsigned mid : 10; /**< Module (processor) ID register. */
unsigned mid : 10; /**< Agent ID in US-IV+ manual.*/
uint64_t : 17;
#endif
} __attribute__ ((packed));
/branches/sparc/kernel/arch/sparc64/src/smp/smp.c
117,8 → 117,6
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++)
/branches/sparc/kernel/arch/sparc64/src/mm/tlb.c
382,38 → 382,38
tlb_data_t d;
tlb_tag_read_reg_t t;
printf("IT16 contents:\n");
for (i = 0; i < 16; i++) {
d.value = dtlb_data_access_read(TLB_IT16, i);
t.value = dtlb_tag_read_read(TLB_IT16, i);
printf("TLB_ISMALL contents:\n");
for (i = 0; i < tlb_ismall_size(); i++) {
d.value = dtlb_data_access_read(TLB_ISMALL, i);
t.value = dtlb_tag_read_read(TLB_ISMALL, i);
print_tlb_entry(i, t, d);
}
printf("IT128 contents:\n");
for (i = 0; i < 128; i++) {
d.value = dtlb_data_access_read(TLB_IT128, i);
t.value = dtlb_tag_read_read(TLB_IT128, i);
printf("TLB_IBIG contents:\n");
for (i = 0; i < tlb_ibig_size(); i++) {
d.value = dtlb_data_access_read(TLB_IBIG, i);
t.value = dtlb_tag_read_read(TLB_IBIG, i);
print_tlb_entry(i, t, d);
}
printf("DT16 contents:\n");
for (i = 0; i < 16; i++) {
d.value = dtlb_data_access_read(TLB_DT16, i);
t.value = dtlb_tag_read_read(TLB_DT16, i);
printf("TLB_DSMALL contents:\n");
for (i = 0; i < tlb_dsmall_size(); i++) {
d.value = dtlb_data_access_read(TLB_DSMALL, i);
t.value = dtlb_tag_read_read(TLB_DSMALL, i);
print_tlb_entry(i, t, d);
}
printf("DT512_1 contents:\n");
for (i = 0; i < 512; i++) {
d.value = dtlb_data_access_read(TLB_DT512_0, i);
t.value = dtlb_tag_read_read(TLB_DT512_0, i);
printf("TLB_DBIG_1 contents:\n");
for (i = 0; i < tlb_dbig_size(); i++) {
d.value = dtlb_data_access_read(TLB_DBIG_0, i);
t.value = dtlb_tag_read_read(TLB_DBIG_0, i);
print_tlb_entry(i, t, d);
}
printf("DT512_2 contents:\n");
for (i = 0; i < 512; i++) {
d.value = dtlb_data_access_read(TLB_DT512_1, i);
t.value = dtlb_tag_read_read(TLB_DT512_1, i);
printf("TLB_DBIG_2 contents:\n");
for (i = 0; i < tlb_dbig_size(); i++) {
d.value = dtlb_data_access_read(TLB_DBIG_1, i);
t.value = dtlb_tag_read_read(TLB_DBIG_1, i);
print_tlb_entry(i, t, d);
}
}
486,8 → 486,8
/** Invalidates given TLB entry if and only if it is non-locked or global.
*
* @param tlb
* TLB number (one of TLB_DT16, TLB_DT512_0, TLB_DT512_1,
* TLB_IT16, TLB_IT128)
* TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1,
* TLB_ISMALL, TLB_IBIG)
* @param entry entry index within the given TLB
*/
static void tlb_invalidate_entry(int tlb, index_t entry)
495,7 → 495,7
tlb_data_t d;
tlb_tag_read_reg_t t;
if (tlb == TLB_DT16 || tlb == TLB_DT512_0 || tlb == TLB_DT512_1) {
if (tlb == TLB_DSMALL || tlb == TLB_DBIG_0 || tlb == TLB_DBIG_1) {
d.value = dtlb_data_access_read(tlb, entry);
if (!d.l || d.g) {
t.value = dtlb_tag_read_read(tlb, entry);
503,7 → 503,7
dtlb_tag_access_write(t.value);
dtlb_data_access_write(tlb, entry, d.value);
}
} else if (tlb == TLB_IT16 || tlb == TLB_IT128) {
} else if (tlb == TLB_ISMALL || tlb == TLB_IBIG) {
d.value = itlb_data_access_read(tlb, entry);
if (!d.l || d.g) {
t.value = itlb_tag_read_read(tlb, entry);
555,16 → 555,16
 
#elif defined (US3)
 
for (i = 0; i < 16; i++)
tlb_invalidate_entry(TLB_IT16, i);
for (i = 0; i < 128; i++)
tlb_invalidate_entry(TLB_IT128, i);
for (i = 0; i < 16; i++)
tlb_invalidate_entry(TLB_DT16, i);
for (i = 0; i < 512; i++)
tlb_invalidate_entry(TLB_DT512_0, i);
for (i = 0; i < 512; i++)
tlb_invalidate_entry(TLB_DT512_1, i);
for (i = 0; i < tlb_ismall_size(); i++)
tlb_invalidate_entry(TLB_ISMALL, i);
for (i = 0; i < tlb_ibig_size(); i++)
tlb_invalidate_entry(TLB_IBIG, i);
for (i = 0; i < tlb_dsmall_size(); i++)
tlb_invalidate_entry(TLB_DSMALL, i);
for (i = 0; i < tlb_dbig_size(); i++)
tlb_invalidate_entry(TLB_DBIG_0, i);
for (i = 0; i < tlb_dbig_size(); i++)
tlb_invalidate_entry(TLB_DBIG_1, i);
#endif
 
}
/branches/sparc/kernel/arch/sparc64/src/mm/cache.S
47,45 → 47,3
retl
! beware SF Erratum #51, do not put the MEMBAR here
nop
 
/** Flush only D-cache lines of one virtual color.
*
* @param o0 Virtual color to be flushed.
*/
.global dcache_flush_color
dcache_flush_color:
mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1
set DCACHE_SIZE / 2, %g2
sllx %g2, %o0, %g2
sub %g2, DCACHE_LINE_SIZE, %g2
0: stxa %g0, [%g2] ASI_DCACHE_TAG
membar #Sync
subcc %g1, 1, %g1
bnz,pt %xcc, 0b
sub %g2, DCACHE_LINE_SIZE, %g2
retl
nop
 
/** Flush only D-cache lines of one virtual color and one tag.
*
* @param o0 Virtual color to lookup the tag.
* @param o1 Tag of the cachelines to be flushed.
*/
.global dcache_flush_tag
dcache_flush_tag:
mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1
set DCACHE_SIZE / 2, %g2
sllx %g2, %o0, %g2
sub %g2, DCACHE_LINE_SIZE, %g2
0: ldxa [%g2] ASI_DCACHE_TAG, %g3
srlx %g3, DCACHE_TAG_SHIFT, %g3
cmp %g3, %o1
bnz 1f
nop
stxa %g0, [%g2] ASI_DCACHE_TAG
membar #Sync
1: subcc %g1, 1, %g1
bnz,pt %xcc, 0b
sub %g2, DCACHE_LINE_SIZE, %g2
retl
nop
/branches/sparc/boot/arch/sparc64/loader/ofwarch.c
58,6 → 58,16
return flag != -1;
}
 
/**
* Starts all CPUs represented by following siblings of the given node,
* except for the current CPU.
*
* @param child the first child of the OFW tree node whose children represent
* CPUs to be woken up
* @param current_mid MID of the current CPU, the current CPU will
* (of course) not be woken up
* @return number of CPUs which have the same parent node as "child"
*/
static int wake_cpus_in_node(phandle child, uint64_t current_mid)
{
int cpus;
87,7 → 97,6
/*
* Start secondary processor.
*/
printf("Starting CPU: %d.\n", mid);
(void) ofw_call("SUNW,start-cpu", 3, 1,
NULL, child, KERNEL_VIRTUAL_ADDRESS,
bootinfo.physmem_start |
100,12 → 109,15
return cpus;
}
 
/**
* Finds out the current CPU's MID and wakes up all AP processors.
*/
int ofw_cpu(void)
{
int cpus;
phandle node;
phandle subnode;
phandle ssm;
phandle cpus_parent;
phandle cmp;
char name[BUF_SIZE];
 
127,25 → 139,24
}
 
/* 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);
}
cpus_parent = ofw_find_device("/ssm@0,0");
if (cpus_parent == 0 || cpus_parent == -1) {
cpus_parent = ofw_find_device("/");
}
 
node = ofw_get_child_node(cpus_parent);
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) {
subnode = ofw_get_child_node(node);
cpus += wake_cpus_in_node(subnode,
current_mid);
}
node = ofw_get_peer_node(node);
}
}
node = ofw_get_peer_node(node);
}
return cpus;
/branches/sparc/usiii.simics
9,9 → 9,9
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 = 1}
if not defined num_cpus {$num_cpus = 2}
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"}
 
###