blob: be730b7516e55bc03ada9f20d54b74079d5368d0 [file] [log] [blame]
Angel Pons585495e2020-04-03 01:21:38 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Stefan Reinauer597ff872013-01-07 13:21:22 -08002
3#include <cbmem.h>
Patrick Rudolph69d5ef92018-11-11 12:43:48 +01004#include <arch/io.h>
Kyösti Mälkkif0a3d442019-08-18 08:02:23 +03005#include <arch/romstage.h>
Nico Huber666c8f82020-07-14 12:22:16 +02006#include <console/console.h>
Arthur Heymans279c3e12020-12-02 13:28:53 +01007#include <cpu/x86/smm.h>
Patrick Rudolph69d5ef92018-11-11 12:43:48 +01008#include "memory.h"
Thomas Heijligen8d010db2019-01-10 19:45:47 +01009#include "fw_cfg.h"
Stefan Reinauer597ff872013-01-07 13:21:22 -080010
11#define CMOS_ADDR_PORT 0x70
12#define CMOS_DATA_PORT 0x71
Gerd Hoffmann9839a382013-06-17 12:26:17 +020013
Stefan Reinauer597ff872013-01-07 13:21:22 -080014#define HIGH_RAM_ADDR 0x35
15#define LOW_RAM_ADDR 0x34
16
Gerd Hoffmann9839a382013-06-17 12:26:17 +020017#define HIGH_HIGHRAM_ADDR 0x5d
18#define MID_HIGHRAM_ADDR 0x5c
19#define LOW_HIGHRAM_ADDR 0x5b
20
Patrick Rudolph69d5ef92018-11-11 12:43:48 +010021unsigned long qemu_get_high_memory_size(void)
22{
23 unsigned long high;
24 outb(HIGH_HIGHRAM_ADDR, CMOS_ADDR_PORT);
Elyes Haouas486240f2022-11-18 15:21:03 +010025 high = ((unsigned long)inb(CMOS_DATA_PORT)) << 22;
Patrick Rudolph69d5ef92018-11-11 12:43:48 +010026 outb(MID_HIGHRAM_ADDR, CMOS_ADDR_PORT);
Elyes Haouas486240f2022-11-18 15:21:03 +010027 high |= ((unsigned long)inb(CMOS_DATA_PORT)) << 14;
Patrick Rudolph69d5ef92018-11-11 12:43:48 +010028 outb(LOW_HIGHRAM_ADDR, CMOS_ADDR_PORT);
Elyes Haouas486240f2022-11-18 15:21:03 +010029 high |= ((unsigned long)inb(CMOS_DATA_PORT)) << 6;
Patrick Rudolph69d5ef92018-11-11 12:43:48 +010030 return high;
31}
32
33unsigned long qemu_get_memory_size(void)
Stefan Reinauer597ff872013-01-07 13:21:22 -080034{
35 unsigned long tomk;
Patrick Rudolph69d5ef92018-11-11 12:43:48 +010036 outb(HIGH_RAM_ADDR, CMOS_ADDR_PORT);
Elyes Haouas486240f2022-11-18 15:21:03 +010037 tomk = ((unsigned long)inb(CMOS_DATA_PORT)) << 14;
Patrick Rudolph69d5ef92018-11-11 12:43:48 +010038 outb(LOW_RAM_ADDR, CMOS_ADDR_PORT);
Elyes Haouas486240f2022-11-18 15:21:03 +010039 tomk |= ((unsigned long)inb(CMOS_DATA_PORT)) << 6;
Stefan Reinauer597ff872013-01-07 13:21:22 -080040 tomk += 16 * 1024;
41 return tomk;
42}
43
Elyes Haouas799c3212022-11-09 14:00:44 +010044uintptr_t cbmem_top_chipset(void)
Stefan Reinauer597ff872013-01-07 13:21:22 -080045{
Thomas Heijligen8d010db2019-01-10 19:45:47 +010046 uintptr_t top = 0;
47
48 top = fw_cfg_tolud();
Nico Huber666c8f82020-07-14 12:22:16 +020049 if (!top) {
50 printk(BIOS_WARNING, "QEMU: Falling back to RAM info in CMOS\n");
Thomas Heijligen8d010db2019-01-10 19:45:47 +010051 top = (uintptr_t)qemu_get_memory_size() * 1024;
Nico Huber666c8f82020-07-14 12:22:16 +020052 }
Thomas Heijligen8d010db2019-01-10 19:45:47 +010053
Arthur Heymans279c3e12020-12-02 13:28:53 +010054 if (CONFIG(BOARD_EMULATION_QEMU_X86_Q35)) {
55 size_t smm_size;
56 smm_region(&top, &smm_size);
57 }
58
Elyes Haouas799c3212022-11-09 14:00:44 +010059 return top;
Stefan Reinauer597ff872013-01-07 13:21:22 -080060}
Kyösti Mälkkif0a3d442019-08-18 08:02:23 +030061
62/* Nothing to do, MTRRs are no-op on QEMU. */
63void fill_postcar_frame(struct postcar_frame *pcf)
64{
65}