cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

id.c (6373B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * linux/arch/arm/mach-omap1/id.c
      4 *
      5 * OMAP1 CPU identification code
      6 *
      7 * Copyright (C) 2004 Nokia Corporation
      8 * Written by Tony Lindgren <tony@atomide.com>
      9 */
     10
     11#include <linux/module.h>
     12#include <linux/kernel.h>
     13#include <linux/init.h>
     14#include <linux/io.h>
     15#include <linux/soc/ti/omap1-io.h>
     16#include <asm/system_info.h>
     17
     18#include "soc.h"
     19#include "hardware.h"
     20#include "common.h"
     21
     22#define OMAP_DIE_ID_0		0xfffe1800
     23#define OMAP_DIE_ID_1		0xfffe1804
     24#define OMAP_PRODUCTION_ID_0	0xfffe2000
     25#define OMAP_PRODUCTION_ID_1	0xfffe2004
     26#define OMAP32_ID_0		0xfffed400
     27#define OMAP32_ID_1		0xfffed404
     28
     29struct omap_id {
     30	u16	jtag_id;	/* Used to determine OMAP type */
     31	u8	die_rev;	/* Processor revision */
     32	u32	omap_id;	/* OMAP revision */
     33	u32	type;		/* Cpu id bits [31:08], cpu class bits [07:00] */
     34};
     35
     36static unsigned int omap_revision;
     37
     38/* Register values to detect the OMAP version */
     39static struct omap_id omap_ids[] __initdata = {
     40	{ .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000},
     41	{ .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
     42	{ .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
     43	{ .jtag_id = 0xb62c, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x08500000},
     44	{ .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
     45	{ .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000},
     46	{ .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000},
     47	{ .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00},
     48	{ .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00},
     49	{ .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
     50	{ .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
     51	{ .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000},
     52	{ .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00},
     53	{ .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00},
     54	{ .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300},
     55	{ .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300},
     56	{ .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300},
     57	{ .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000},
     58	{ .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000},
     59	{ .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000},
     60};
     61
     62unsigned int omap_rev(void)
     63{
     64	return omap_revision;
     65}
     66EXPORT_SYMBOL(omap_rev);
     67
     68/*
     69 * Get OMAP type from PROD_ID.
     70 * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM.
     71 * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense.
     72 * Undocumented register in TEST BLOCK is used as fallback; This seems to
     73 * work on 1510, 1610 & 1710. The official way hopefully will work in future
     74 * processors.
     75 */
     76static u16 __init omap_get_jtag_id(void)
     77{
     78	u32 prod_id, omap_id;
     79
     80	prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
     81	omap_id = omap_readl(OMAP32_ID_1);
     82
     83	/* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730/850 */
     84	if (((prod_id >> 20) == 0) || (prod_id == omap_id))
     85		prod_id = 0;
     86	else
     87		prod_id &= 0xffff;
     88
     89	if (prod_id)
     90		return prod_id;
     91
     92	/* Use OMAP32_ID_1 as fallback */
     93	prod_id = ((omap_id >> 12) & 0xffff);
     94
     95	return prod_id;
     96}
     97
     98/*
     99 * Get OMAP revision from DIE_REV.
    100 * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID.
    101 * Undocumented register in the TEST BLOCK is used as fallback.
    102 * REVISIT: This does not seem to work on 1510
    103 */
    104static u8 __init omap_get_die_rev(void)
    105{
    106	u32 die_rev;
    107
    108	die_rev = omap_readl(OMAP_DIE_ID_1);
    109
    110	/* Check for broken OMAP_DIE_ID on early 1710 */
    111	if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id())
    112		die_rev = 0;
    113
    114	die_rev = (die_rev >> 17) & 0xf;
    115	if (die_rev)
    116		return die_rev;
    117
    118	die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf;
    119
    120	return die_rev;
    121}
    122
    123void __init omap_check_revision(void)
    124{
    125	int i;
    126	u16 jtag_id;
    127	u8 die_rev;
    128	u32 omap_id;
    129	u8 cpu_type;
    130
    131	jtag_id = omap_get_jtag_id();
    132	die_rev = omap_get_die_rev();
    133	omap_id = omap_readl(OMAP32_ID_0);
    134
    135#ifdef DEBUG
    136	printk(KERN_DEBUG "OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0));
    137	printk(KERN_DEBUG "OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n",
    138		omap_readl(OMAP_DIE_ID_1),
    139	       (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf);
    140	printk(KERN_DEBUG "OMAP_PRODUCTION_ID_0: 0x%08x\n",
    141		omap_readl(OMAP_PRODUCTION_ID_0));
    142	printk(KERN_DEBUG "OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n",
    143		omap_readl(OMAP_PRODUCTION_ID_1),
    144		omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff);
    145	printk(KERN_DEBUG "OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0));
    146	printk(KERN_DEBUG "OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1));
    147	printk(KERN_DEBUG "JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev);
    148#endif
    149
    150	system_serial_high = omap_readl(OMAP_DIE_ID_0);
    151	system_serial_low = omap_readl(OMAP_DIE_ID_1);
    152
    153	/* First check only the major version in a safe way */
    154	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
    155		if (jtag_id == (omap_ids[i].jtag_id)) {
    156			omap_revision = omap_ids[i].type;
    157			break;
    158		}
    159	}
    160
    161	/* Check if we can find the die revision */
    162	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
    163		if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) {
    164			omap_revision = omap_ids[i].type;
    165			break;
    166		}
    167	}
    168
    169	/* Finally check also the omap_id */
    170	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
    171		if (jtag_id == omap_ids[i].jtag_id
    172		    && die_rev == omap_ids[i].die_rev
    173		    && omap_id == omap_ids[i].omap_id) {
    174			omap_revision = omap_ids[i].type;
    175			break;
    176		}
    177	}
    178
    179	/* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */
    180	cpu_type = omap_revision >> 24;
    181
    182	switch (cpu_type) {
    183	case 0x07:
    184	case 0x08:
    185		omap_revision |= 0x07;
    186		break;
    187	case 0x03:
    188	case 0x15:
    189		omap_revision |= 0x15;
    190		break;
    191	case 0x16:
    192	case 0x17:
    193		omap_revision |= 0x16;
    194		break;
    195	default:
    196		printk(KERN_INFO "Unknown OMAP cpu type: 0x%02x\n", cpu_type);
    197	}
    198
    199	pr_info("OMAP%04x", omap_revision >> 16);
    200	if ((omap_revision >> 8) & 0xff)
    201		pr_cont("%x", (omap_revision >> 8) & 0xff);
    202	pr_cont(" revision %i handled as %02xxx id: %08x%08x\n",
    203	       die_rev, omap_revision & 0xff, system_serial_low,
    204	       system_serial_high);
    205}
    206