1/* 2 * This file is part of the coreboot project. 3 * 4 * Copyright (C) 2006 Indrek Kruusa <indrek.kruusa@artecdesign.ee> 5 * Copyright (C) 2006 Ronald G. Minnich <rminnich@gmail.com> 6 * Copyright (C) 2006 Stefan Reinauer <stepan@coresystems.de> 7 * Copyright (C) 2006 Andrei Birjukov <andrei.birjukov@artecdesign.ee> 8 * Copyright (C) 2007 Advanced Micro Devices, Inc. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25/* This is a test for the idea of a CPU device. There is only ever going to 26 * be one CPU device, the bootstrap processor or BP; other processors will 27 * go through a different path. On Geode it is really simple, so we start 28 * with that. Later, it gets harder. 29 */ 30 31#include <console.h> 32#include <device/device.h> 33#include <lib.h> 34#include <io.h> 35#include <cpu.h> 36 37/* TODO: Better comment on vsm_end_post_smi, and define 0x05a2 down below. */ 38 39/** 40 * This is a call to the VSM. 41 * 42 * TODO: We need to know what it does. 43 */ 44static void vsm_end_post_smi(void) 45{ 46 __asm__ volatile("push %ax\n" 47 "mov $0x5000, %ax\n" 48 ".byte 0x0f, 0x38\n" 49 "pop %ax\n"); 50} 51 52/** 53 * The very last steps in LX init. Turn on caching, tell VSM that we are 54 * done. Turn A20 back on in case VSM turned it off. 55 * 56 * @param dev The device to use. 57 */ 58static void lx_init(struct device *dev) 59{ 60 printk(BIOS_SPEW, "CPU lx_init\n"); 61 62 /* Turn on caching if we haven't already. */ 63 enable_cache(); 64 65 /* Do VSA late init. */ 66 vsm_end_post_smi(); 67 68 /* Set gate A20 (legacy VSM disables it in late init). */ 69 printk(BIOS_SPEW, "A20 (0x92): %d\n", inb(0x92)); 70 outb(0x02, 0x92); 71 printk(BIOS_SPEW, "A20 (0x92): %d\n", inb(0x92)); 72 73 printk(BIOS_SPEW, "CPU lx_init DONE\n"); 74}; 75 76/** 77 * Device operations for the CPU. 78 * 79 * Later, we might need to change it to use a different phase3_scan, and 80 * match on a CPU ID. However, CPU IDs are known to be kind of weird, 81 * depending on date manufactured they can be all over the place (the Geode 82 * alone has had 3 vendors!) so we will have to be careful. 83 */ 84/** 85 * The only operations currently set up are the phase 6. We might, however, 86 * set up an op in phase3_scan to get the cpuinfo into a struct for all to 87 * see. On SMP, it would not be hard to have phase3_scan set up an array of 88 * such structs. 89 * 90 * Further, for systems which have multiple types of CPUs, you can compile 91 * in multiple CPU files and use the device ID, at scan time, to pick which 92 * one is used. There is a lot of flexibility here! 93 */ 94struct device_operations geodelx_cpuops = { 95 {.id = {.type = DEVICE_ID_PCI, 96 /* TODO: This is incorrect, these are _not_ PCI IDs! */ 97 {.pci = {.vendor = X86_VENDOR_AMD,.device = 0x05A2}}}, 98 .ops = &geodelx_cpuops} .constructor = default_device_constructor, 99 .phase3_scan = NULL, 100 .phase6_init = lx_init, 101}; 102

