2 * This file is part of the coreboot project.
4 * Copyright (C) 2007-2009 coresystems GmbH
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <console/console.h>
19 #include <device/device.h>
20 #include <device/pci.h>
21 #include <device/hypertransport.h>
22 #include <device/pci_ids.h>
26 #include <cpu/x86/mtrr.h>
28 #include <arch/acpi.h>
30 static void pci_domain_set_resources(device_t dev
)
35 unsigned long tomk
, tolmk
;
36 unsigned char rambits
;
39 pci_tolm
= find_pci_tolm(dev
->link_list
);
40 mc_dev
= dev_find_device(PCI_VENDOR_ID_VIA
, 0x3324, 0);
42 rambits
= pci_read_config8(mc_dev
, 0x88);
45 /* Get memory size and frame buffer from northbridge's registers.
47 * If register contains an invalid value we set frame buffer size to a
48 * default of 32M, but that probably won't happen.
50 reg
= pci_read_config8(mc_dev
, 0xa1);
54 /* TOP 1M SMM Memory */
55 if (reg
== 0x0 || reg
== 0x6 || reg
== 0x7)
56 tomk
= (((rambits
<< 6) - 32 - 1) * 1024); // Set frame buffer 32M for default
58 tomk
= (((rambits
<< 6) - (4 << reg
) - 1) * 1024);
60 /* Compute the top of Low memory */
61 tolmk
= pci_tolm
>> 10;
63 /* The PCI hole does does not overlap the memory. */
65 tolmk
-= 1024; // TOP 1M SM Memory
68 set_top_of_ram(tolmk
* 1024);
70 /* Report the memory regions */
73 /* TODO: Hole needed? Should this go elsewhere? */
74 ram_resource(dev
, idx
++, 0, 640); /* first 640k */
75 ram_resource(dev
, idx
++, 768, (tolmk
- 768)); /* leave a hole for vga */
76 assign_resources(dev
->link_list
);
79 unsigned long acpi_fill_mcfg(unsigned long current
)
84 dev
= dev_find_device(0x1106, 0x324b, 0); // 0:0x13.0
88 // MMCFG not supported or not enabled.
89 if ((pci_read_config8(dev
, 0x40) & 0xC0) != 0xC0)
92 mmcfg
= ((u64
) pci_read_config8(dev
, 0x41)) << 28;
96 current
+= acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t
*) current
, mmcfg
, 0x0, 0x0, 0xff);
101 static struct device_operations pci_domain_ops
= {
102 .read_resources
= pci_domain_read_resources
,
103 .set_resources
= pci_domain_set_resources
,
104 .enable_resources
= NULL
,
106 .scan_bus
= pci_domain_scan_bus
,
107 .ops_pci_bus
= pci_bus_default_ops
,
108 .write_acpi_tables
= acpi_write_hpet
,
111 static void cpu_bus_init(device_t dev
)
113 initialize_cpus(dev
->link_list
);
116 static struct device_operations cpu_bus_ops
= {
117 .read_resources
= DEVICE_NOOP
,
118 .set_resources
= DEVICE_NOOP
,
119 .enable_resources
= DEVICE_NOOP
,
120 .init
= cpu_bus_init
,
124 static void enable_dev(struct device
*dev
)
126 /* Our wonderful device model */
127 if (dev
->path
.type
== DEVICE_PATH_DOMAIN
) {
128 dev
->ops
= &pci_domain_ops
;
129 } else if (dev
->path
.type
== DEVICE_PATH_CPU_CLUSTER
) {
130 dev
->ops
= &cpu_bus_ops
;
134 struct chip_operations northbridge_via_cx700_ops
= {
135 CHIP_NAME("VIA CX700 Northbridge")
136 .enable_dev
= enable_dev