/* * Intel CPU Microcode Update Driver for Linux * * Copyright (C) 2000-2006 Tigran Aivazian * 2006 Shaohua Li * * This driver allows to upgrade microcode on Intel processors * belonging to IA-32 family - PentiumPro, Pentium II, * Pentium III, Xeon, Pentium 4, etc. * * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture * Software Developer's Manual * Order Number 253668 or free download from: * * http://developer.intel.com/design/pentium4/manuals/253668.htm * * For more information, go to http://www.urbanmyth.org/microcode * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include #include #include #include #include #include const struct microcode_ops *microcode_ops; static DEFINE_SPINLOCK(microcode_mutex); struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; struct microcode_info { unsigned int cpu; uint32_t buffer_size; int error; char buffer[1]; }; static void __microcode_fini_cpu(int cpu) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu; xfree(uci->mc.mc_valid); memset(uci, 0, sizeof(*uci)); } static void microcode_fini_cpu(int cpu) { spin_lock(µcode_mutex); __microcode_fini_cpu(cpu); spin_unlock(µcode_mutex); } int microcode_resume_cpu(int cpu) { int err = 0; struct ucode_cpu_info *uci = ucode_cpu_info + cpu; struct cpu_signature nsig; gdprintk(XENLOG_INFO, "microcode: CPU%d resumed\n", cpu); if ( !uci->mc.mc_valid ) return -EIO; /* * Let's verify that the 'cached' ucode does belong * to this cpu (a bit of paranoia): */ err = microcode_ops->collect_cpu_info(cpu, &nsig); if ( err ) { microcode_fini_cpu(cpu); return err; } if ( microcode_ops->microcode_resume_match(cpu, &nsig) ) { return microcode_ops->apply_microcode(cpu); } else { microcode_fini_cpu(cpu); return -EIO; } } static int microcode_update_cpu(const void *buf, size_t size) { int err; unsigned int cpu = smp_processor_id(); struct ucode_cpu_info *uci = ucode_cpu_info + cpu; spin_lock(µcode_mutex); err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); if ( likely(!err) ) err = microcode_ops->cpu_request_microcode(cpu, buf, size); else __microcode_fini_cpu(cpu); spin_unlock(µcode_mutex); return err; } static long do_microcode_update(void *_info) { struct microcode_info *info = _info; int error; BUG_ON(info->cpu != smp_processor_id()); error = microcode_update_cpu(info->buffer, info->buffer_size); if ( error ) info->error = error; info->cpu = next_cpu(info->cpu, cpu_online_map); if ( info->cpu < NR_CPUS ) return continue_hypercall_on_cpu(info->cpu, do_microcode_update, info); error = info->error; xfree(info); return error; } int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len) { int ret; struct microcode_info *info; if ( len != (uint32_t)len ) return -E2BIG; if ( microcode_ops == NULL ) return -EINVAL; info = xmalloc_bytes(sizeof(*info) + len); if ( info == NULL ) return -ENOMEM; ret = copy_from_guest(info->buffer, buf, len); if ( ret != 0 ) { xfree(info); return ret; } info->buffer_size = len; info->error = 0; info->cpu = first_cpu(cpu_online_map); return continue_hypercall_on_cpu(info->cpu, do_microcode_update, info); } 8d01a2961dbb947e63928'>plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*
 * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions.
 *
 * Copyright 2004, Broadcom Corporation      
 * All Rights Reserved.      
 *       
 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY      
 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM      
 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS      
 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.      
 * $Id$
 */

#ifndef	_SBSDRAM_H
#define	_SBSDRAM_H

#ifndef _LANGUAGE_ASSEMBLY

/* Sonics side: SDRAM core registers */
typedef volatile struct sbsdramregs {
	uint32	initcontrol;	/* Generates external SDRAM initialization sequence */
	uint32	config;		/* Initializes external SDRAM mode register */
	uint32	refresh;	/* Controls external SDRAM refresh rate */
	uint32	pad1;
	uint32	pad2;
} sbsdramregs_t;

#endif

/* SDRAM initialization control (initcontrol) register bits */
#define SDRAM_CBR	0x0001	/* Writing 1 generates refresh cycle and toggles bit */
#define SDRAM_PRE	0x0002	/* Writing 1 generates precharge cycle and toggles bit */
#define SDRAM_MRS	0x0004	/* Writing 1 generates mode register select cycle and toggles bit */
#define SDRAM_EN	0x0008	/* When set, enables access to SDRAM */
#define SDRAM_16Mb	0x0000	/* Use 16 Megabit SDRAM */
#define SDRAM_64Mb	0x0010	/* Use 64 Megabit SDRAM */
#define SDRAM_128Mb	0x0020	/* Use 128 Megabit SDRAM */
#define SDRAM_RSVMb	0x0030	/* Use special SDRAM */
#define SDRAM_RST	0x0080	/* Writing 1 causes soft reset of controller */
#define SDRAM_SELFREF	0x0100	/* Writing 1 enables self refresh mode */
#define SDRAM_PWRDOWN	0x0200	/* Writing 1 causes controller to power down */
#define SDRAM_32BIT	0x0400	/* When set, indicates 32 bit SDRAM interface */
#define SDRAM_9BITCOL	0x0800	/* When set, indicates 9 bit column */

/* SDRAM configuration (config) register bits */
#define SDRAM_BURSTFULL	0x0000	/* Use full page bursts */
#define SDRAM_BURST8	0x0001	/* Use burst of 8 */
#define SDRAM_BURST4	0x0002	/* Use burst of 4 */
#define SDRAM_BURST2	0x0003	/* Use burst of 2 */
#define SDRAM_CAS3	0x0000	/* Use CAS latency of 3 */
#define SDRAM_CAS2	0x0004	/* Use CAS latency of 2 */

/* SDRAM refresh control (refresh) register bits */
#define SDRAM_REF(p)	(((p)&0xff) | SDRAM_REF_EN)	/* Refresh period */
#define SDRAM_REF_EN	0x8000		/* Writing 1 enables periodic refresh */

/* SDRAM Core default Init values (OCP ID 0x803) */
#define SDRAM_INIT	MEM4MX16X2
#define SDRAM_CONFIG    SDRAM_BURSTFULL
#define SDRAM_REFRESH   SDRAM_REF(0x40)

#define MEM1MX16	0x009	/* 2 MB */
#define MEM1MX16X2	0x409	/* 4 MB */
#define MEM2MX8X2	0x809	/* 4 MB */
#define MEM2MX8X4	0xc09	/* 8 MB */
#define MEM2MX32	0x439	/* 8 MB */
#define MEM4MX16	0x019	/* 8 MB */
#define MEM4MX16X2	0x419	/* 16 MB */
#define MEM8MX8X2	0x819	/* 16 MB */
#define MEM8MX16	0x829	/* 16 MB */
#define MEM4MX32	0x429	/* 16 MB */
#define MEM8MX8X4	0xc19	/* 32 MB */
#define MEM8MX16X2	0xc29	/* 32 MB */

#endif	/* _SBSDRAM_H */