/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"} |
### |