{ 0x17, 0x13, 0, "UltraSparc IIe integrated FPU"},
{ 0x3e, 0x14, 0, "UltraSparc III integrated FPU"},
{ 0x3e, 0x15, 0, "UltraSparc III+ integrated FPU"},
+ { 0x3e, 0x16, 0, "UltraSparc IIIi integrated FPU"},
};
#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info))
{ 0x17, 0x10, "TI UltraSparc I (SpitFire)"},
{ 0x22, 0x10, "TI UltraSparc I (SpitFire)"},
{ 0x17, 0x11, "TI UltraSparc II (BlackBird)"},
- { 0x17, 0x12, "TI UltraSparc IIi"},
- { 0x17, 0x13, "TI UltraSparc IIe"},
+ { 0x17, 0x12, "TI UltraSparc IIi (Sabre)"},
+ { 0x17, 0x13, "TI UltraSparc IIe (Hummingbird)"},
{ 0x3e, 0x14, "TI UltraSparc III (Cheetah)"},
{ 0x3e, 0x15, "TI UltraSparc III+ (Cheetah+)"},
+ { 0x3e, 0x16, "TI UltraSparc IIIi (Jalapeno)"},
};
#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info))
#endif
static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, unsigned long mask)
{
- u64 pstate;
- int nack_busy_id;
+ u64 pstate, ver;
+ int nack_busy_id, is_jalapeno;
if (!mask)
return;
+ /* Unfortunately, someone at Sun had the brilliant idea to make the
+ * busy/nack fields hard-coded by ITID number for this Ultra-III
+ * derivative processor.
+ */
+ __asm__ ("rdpr %%ver, %0" : "=r" (ver));
+ is_jalapeno = ((ver >> 32) == 0x003e0016);
+
__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
retry:
if (work_mask & (1UL << i)) {
u64 target = (i << 14) | 0x70;
- target |= (nack_busy_id++ << 24);
+ if (!is_jalapeno)
+ target |= (nack_busy_id << 24);
__asm__ __volatile__(
"stxa %%g0, [%0] %1\n\t"
"membar #Sync\n\t"
: /* no outputs */
: "r" (target), "i" (ASI_INTR_W));
+ nack_busy_id++;
work_mask &= ~(1UL << i);
if (!work_mask)
break;
*/
for (i = 0; i < NR_CPUS; i++) {
if (work_mask & (1UL << i)) {
- if ((dispatch_stat &
- (0x2 << this_busy_nack)) == 0)
+ u64 check_mask;
+
+ if (is_jalapeno)
+ check_mask = (0x2UL << (2*i));
+ else
+ check_mask = (0x2UL <<
+ this_busy_nack);
+ if ((dispatch_stat & check_mask) == 0)
mask &= ~(1UL << i);
this_busy_nack += 2;
work_mask &= ~(1UL << i);