blob: 31306fbe31a07d3800a2c1065415f646384dc631 [file] [log] [blame]
Stefan Reinauerdebb11f2008-10-29 04:46:52 +00001/*
2 * This file is part of the coreboot project.
3 *
Stefan Reinauer54309d62009-01-20 22:53:10 +00004 * Copyright (C) 2008-2009 coresystems GmbH
Stefan Reinauerdebb11f2008-10-29 04:46:52 +00005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000015 */
16
Stefan Reinauer573f7d42009-07-21 21:50:34 +000017#include <types.h>
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000018#include <console/console.h>
19#include <cpu/x86/cache.h>
20#include <cpu/x86/smm.h>
Stefan Reinauer7a3d0952010-01-17 13:49:07 +000021#include <device/pci_def.h>
Sven Schnelle811787a2011-06-29 15:05:28 +020022#include <pc80/mc146818rtc.h>
Arthur Heymans31312b22018-04-10 12:56:19 +020023#include <southbridge/intel/common/pmutil.h>
Stefan Reinauer573f7d42009-07-21 21:50:34 +000024#include "i82801gx.h"
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000025
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000026/* I945 */
27#define SMRAM 0x9d
28#define D_OPEN (1 << 6)
29#define D_CLS (1 << 5)
30#define D_LCK (1 << 4)
31#define G_SMRANE (1 << 3)
32#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
33
stepan836ae292010-12-08 05:42:47 +000034#include "nvs.h"
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000035
36/* While we read PMBASE dynamically in case it changed, let's
37 * initialize it with a sane value
38 */
Stefan Reinauer573f7d42009-07-21 21:50:34 +000039u16 pmbase = DEFAULT_PMBASE;
Stefan Reinaueraca6ec62009-10-26 17:12:21 +000040u8 smm_initialized = 0;
Stefan Reinauer573f7d42009-07-21 21:50:34 +000041
42/* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
43 * by coreboot.
44 */
45global_nvs_t *gnvs = (global_nvs_t *)0x0;
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000046
Arthur Heymans31312b22018-04-10 12:56:19 +020047void southbridge_update_gnvs(u8 apm_cnt, int *smm_done)
Kyösti Mälkkib85a87b2014-12-29 11:32:27 +020048{
Arthur Heymans31312b22018-04-10 12:56:19 +020049 gnvs = *(global_nvs_t **)0x500;
50 *smm_done = 1;
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000051}
52
Stefan Reinauer3b387452009-03-06 19:52:36 +000053int southbridge_io_trap_handler(int smif)
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000054{
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000055 switch (smif) {
56 case 0x32:
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000057 printk(BIOS_DEBUG, "OS Init\n");
Stefan Reinaueraca6ec62009-10-26 17:12:21 +000058 /* gnvs->smif:
59 * On success, the IO Trap Handler returns 0
60 * On failure, the IO Trap Handler returns a value != 0
61 */
Stefan Reinauer573f7d42009-07-21 21:50:34 +000062 gnvs->smif = 0;
Stefan Reinaueraca6ec62009-10-26 17:12:21 +000063 return 1; /* IO trap handled */
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000064 }
65
Stefan Reinaueraca6ec62009-10-26 17:12:21 +000066 /* Not handled */
67 return 0;
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000068}
69
Arthur Heymans31312b22018-04-10 12:56:19 +020070void southbridge_smi_monitor(void)
Stefan Reinauer573f7d42009-07-21 21:50:34 +000071{
72#define IOTRAP(x) (trap_sts & (1 << x))
73 u32 trap_sts, trap_cycle;
74 u32 data, mask = 0;
75 int i;
76
77 trap_sts = RCBA32(0x1e00); // TRSR - Trap Status Register
78 RCBA32(0x1e00) = trap_sts; // Clear trap(s) in TRSR
79
80 trap_cycle = RCBA32(0x1e10);
Arthur Heymans3f111b02017-03-09 12:02:52 +010081 for (i = 16; i < 20; i++) {
Stefan Reinauer573f7d42009-07-21 21:50:34 +000082 if (trap_cycle & (1 << i))
83 mask |= (0xff << ((i - 16) << 2));
84 }
85
86
87 /* IOTRAP(3) SMI function call */
88 if (IOTRAP(3)) {
89 if (gnvs && gnvs->smif)
90 io_trap_handler(gnvs->smif); // call function smif
91 return;
92 }
93
94 /* IOTRAP(2) currently unused
95 * IOTRAP(1) currently unused */
96
Vladimir Serbinenkoa4857052014-08-31 01:09:12 +020097 /* IOTRAP(0) SMIC: currently unused */
Stefan Reinauer573f7d42009-07-21 21:50:34 +000098
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000099 printk(BIOS_DEBUG, " trapped io address = 0x%x\n", trap_cycle & 0xfffc);
Arthur Heymans3f111b02017-03-09 12:02:52 +0100100 for (i = 0; i < 4; i++)
101 if (IOTRAP(i))
102 printk(BIOS_DEBUG, " TRAP = %d\n", i);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000103 printk(BIOS_DEBUG, " AHBE = %x\n", (trap_cycle >> 16) & 0xf);
104 printk(BIOS_DEBUG, " MASK = 0x%08x\n", mask);
105 printk(BIOS_DEBUG, " read/write: %s\n", (trap_cycle & (1 << 24)) ? "read" : "write");
Stefan Reinauer573f7d42009-07-21 21:50:34 +0000106
107 if (!(trap_cycle & (1 << 24))) {
108 /* Write Cycle */
109 data = RCBA32(0x1e18);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000110 printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", data);
Stefan Reinauer573f7d42009-07-21 21:50:34 +0000111 }
112#undef IOTRAP
113}
114
Arthur Heymans31312b22018-04-10 12:56:19 +0200115void southbridge_finalize_all(void)
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000116{
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000117}