/branches/sparc/kernel/arch/sparc64/include/regdef.h |
---|
60,11 → 60,6 |
* 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/asm.h |
---|
136,6 → 136,28 |
asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0)); |
} |
/** Read STICK_compare Register. |
* |
* @return Value of STICK_compare register. |
*/ |
static inline uint64_t stick_compare_read(void) |
{ |
uint64_t v; |
asm volatile ("rd %%asr25, %0\n" : "=r" (v)); |
return v; |
} |
/** Write STICK_compare Register. |
* |
* @param v New value of STICK_comapre register. |
*/ |
static inline void stick_compare_write(uint64_t v) |
{ |
asm volatile ("wr %0, %1, %%asr25\n" : : "r" (v), "i" (0)); |
} |
/** Read TICK Register. |
* |
* @return Value of TICK register. |
407,17 → 429,6 |
asm volatile ("wrpr %g0, %g0, %tl\n"); |
} |
/** Read UPA_CONFIG/FIREPLANE_CONFIG register. |
* |
* @return |
* Value of the UPA_CONFIG register in US, |
* value of the FIREPLANE_CONFIG on US3. |
*/ |
static inline uint64_t icbus_config_read(void) |
{ |
return asi_u64_read(ASI_ICBUS_CONFIG, 0); |
} |
extern void cpu_halt(void); |
extern void cpu_sleep(void); |
extern void asm_delay_loop(const uint32_t usec); |
/branches/sparc/kernel/arch/sparc64/include/register.h |
---|
117,30 → 117,7 |
}; |
typedef union fprs_reg fprs_reg_t; |
/** UPA_CONFIG/FIREPLANE_CONFIG register. |
* |
* Note that format of this register differs significantly from |
* processor version to version. The format defined here |
* is the common subset for all supported processor versions. |
*/ |
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; /**< Agent ID in US-IV+ manual.*/ |
uint64_t : 17; |
#endif |
} __attribute__ ((packed)); |
}; |
typedef union icbus_config icbus_config_t; |
#endif |
/** @} |
*/ |
/branches/sparc/kernel/arch/sparc64/include/cpu.h |
---|
35,15 → 35,6 |
#ifndef KERN_sparc64_CPU_H_ |
#define KERN_sparc64_CPU_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/register.h> |
#include <arch/asm.h> |
#ifdef CONFIG_SMP |
#include <arch/mm/cache.h> |
#endif |
#define MANUF_FUJITSU 0x04 |
#define MANUF_ULTRASPARC 0x17 /**< UltraSPARC I, UltraSPARC II */ |
#define MANUF_SUN 0x3e |
60,6 → 51,18 |
#define IMPL_SPARC64V 0x5 |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/register.h> |
#include <arch/regdef.h> |
#include <arch/asm.h> |
#ifdef CONFIG_SMP |
#include <arch/mm/cache.h> |
#endif |
typedef struct { |
uint32_t mid; /**< Processor ID as read from |
UPA_CONFIG/FIREPLANE_CONFIG. */ |
70,7 → 73,27 |
matches this value. */ |
} cpu_arch_t; |
/** |
* Reads the module ID (agent ID/CPUID) of the current CPU. |
*/ |
static inline uint32_t read_mid(void) |
{ |
uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0); |
icbus_config = icbus_config >> ICBUS_CONFIG_MID_SHIFT; |
#if defined (US) |
return icbus_config & 0x1f; |
#elif defined (US3) |
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIII_I) |
return icbus_config & 0x1f; |
else |
return icbus_config & 0x3ff; |
#endif |
} |
#endif |
#endif |
/** @} |
*/ |
/branches/sparc/kernel/arch/sparc64/include/drivers/scr.h |
---|
42,7 → 42,8 |
SCR_UNKNOWN, |
SCR_ATYFB, |
SCR_FFB, |
SCR_CGSIX |
SCR_CGSIX, |
SCR_XVR |
} scr_type_t; |
extern scr_type_t scr_type; |
/branches/sparc/kernel/arch/sparc64/src/cpu/cpu.c |
---|
79,10 → 79,8 |
{ |
ofw_tree_node_t *node; |
uint32_t clock_frequency = 0; |
icbus_config_t icbus_config; |
icbus_config.value = icbus_config_read(); |
CPU->arch.mid = icbus_config.mid; |
CPU->arch.mid = read_mid(); |
/* |
* Detect processor frequency. |
/branches/sparc/kernel/arch/sparc64/src/drivers/scr.c |
---|
61,6 → 61,8 |
if (strcmp(name, "SUNW,m64B") == 0) |
scr_type = SCR_ATYFB; |
else if (strcmp(name, "SUNW,XVR-100") == 0) |
scr_type = SCR_XVR; |
else if (strcmp(name, "SUNW,ffb") == 0) |
scr_type = SCR_FFB; |
else if (strcmp(name, "cgsix") == 0) |
67,7 → 69,7 |
scr_type = SCR_CGSIX; |
if (scr_type == SCR_UNKNOWN) { |
printf("Unknown keyboard device.\n"); |
printf("Unknown screen device.\n"); |
return; |
} |
142,6 → 144,50 |
} |
break; |
case SCR_XVR: |
{ |
if (prop->size / sizeof(ofw_pci_reg_t) < 2) { |
printf("Too few screen registers.\n"); |
return; |
} |
ofw_pci_reg_t *fb_reg = &((ofw_pci_reg_t *) prop->value)[1]; |
ofw_pci_reg_t abs_reg; |
if (!ofw_pci_reg_absolutize(node, fb_reg, &abs_reg)) { |
printf("Failed to absolutize fb register.\n"); |
return; |
} |
if (!ofw_pci_apply_ranges(node->parent, &abs_reg , &fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
switch (fb_depth) { |
case 8: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_SB1500_PALETTE; |
break; |
case 16: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_RGB_5_6_5; |
break; |
case 24: |
fb_scanline = fb_linebytes * 4; |
visual = VISUAL_RGB_8_8_8_0; |
break; |
case 32: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
printf("Unsupported bits per pixel.\n"); |
return; |
} |
break; |
} |
case SCR_FFB: |
fb_scanline = 8192; |
visual = VISUAL_BGR_0_8_8_8; |
/branches/sparc/kernel/arch/sparc64/src/drivers/tick.c |
---|
45,11 → 45,11 |
#define TICK_RESTART_TIME 50 /* Worst case estimate. */ |
/** Initialize tick interrupt. */ |
/** Initialize tick and stick interrupt. */ |
void tick_init(void) |
{ |
/* initialize TICK interrupt */ |
tick_compare_reg_t compare; |
interrupt_register(14, "tick_int", tick_interrupt); |
compare.int_dis = false; |
compare.tick_cmpr = CPU->arch.clock_frequency / HZ; |
56,6 → 56,21 |
CPU->arch.next_tick_cmpr = compare.tick_cmpr; |
tick_compare_write(compare.value); |
tick_write(0); |
#if defined (US3) |
/* disable STICK interrupts and clear any pending ones */ |
tick_compare_reg_t stick_compare; |
softint_reg_t clear; |
stick_compare.value = stick_compare_read(); |
stick_compare.int_dis = true; |
stick_compare.tick_cmpr = 0; |
stick_compare_write(stick_compare.value); |
clear.value = 0; |
clear.stick_int = 1; |
clear_softint_write(clear.value); |
#endif |
} |
/** Process tick interrupt. |
65,6 → 80,7 |
*/ |
void tick_interrupt(int n, istate_t *istate) |
{ |
softint_reg_t softint, clear; |
uint64_t drift; |
/branches/sparc/kernel/arch/sparc64/src/start.S |
---|
27,6 → 27,7 |
# |
#include <arch/arch.h> |
#include <arch/cpu.h> |
#include <arch/regdef.h> |
#include <arch/boot/boot.h> |
#include <arch/stack.h> |
297,15 → 298,32 |
nop |
1: |
#ifdef CONFIG_SMP |
/* |
* Determine the width of the MID and save its mask to %g3. The width |
* is |
* * 5 for US and US-IIIi, |
* * 10 for US3 except US-IIIi. |
*/ |
#if defined(US) |
mov 0x1f, %g3 |
#elif defined(US3) |
mov 0x3ff, %g3 |
rdpr %ver, %g2 |
sllx %g2, 16, %g2 |
srlx %g2, 48, %g2 |
cmp %g2, IMPL_ULTRASPARCIII_I |
move %xcc, 0x1f, %g3 |
#endif |
/* |
* Read MID from the processor. |
*/ |
1: |
ldxa [%g0] ASI_ICBUS_CONFIG, %g1 |
srlx %g1, ICBUS_CONFIG_MID_SHIFT, %g1 |
and %g1, ICBUS_CONFIG_MID_MASK, %g1 |
and %g1, %g3, %g1 |
#ifdef CONFIG_SMP |
/* |
* Active loop for APs until the BSP picks them up. A processor cannot |
* leave the loop until the global variable 'waking_up_mid' equals its |