2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <amdblocks/biosram.h>
16 #include <device/pci_ops.h>
17 #include <arch/ioapic.h>
18 #include <arch/acpi.h>
19 #include <arch/acpigen.h>
21 #include <console/console.h>
22 #include <cpu/amd/mtrr.h>
23 #include <cpu/x86/lapic_def.h>
24 #include <cpu/x86/msr.h>
25 #include <cpu/amd/msr.h>
26 #include <device/device.h>
27 #include <device/pci.h>
28 #include <device/pci_ids.h>
29 #include <romstage_handoff.h>
30 #include <amdblocks/agesawrapper.h>
31 #include <amdblocks/agesawrapper_call.h>
32 #include <agesa_headers.h>
34 #include <soc/northbridge.h>
35 #include <soc/pci_devs.h>
36 #include <soc/iomap.h>
39 #include <arch/bert_storage.h>
43 static void set_io_addr_reg(struct device
*dev
, u32 nodeid
, u32 linkn
, u32 reg
,
44 u32 io_min
, u32 io_max
)
48 /* io range allocation. Limit */
49 tempreg
= (nodeid
& 0xf) | ((nodeid
& 0x30) << (8 - 4)) | (linkn
<< 4)
50 | ((io_max
& 0xf0) << (12 - 4));
51 pci_write_config32(SOC_ADDR_DEV
, reg
+ 4, tempreg
);
52 tempreg
= 3 | ((io_min
& 0xf0) << (12 - 4)); /* base: ISA and VGA ? */
53 pci_write_config32(SOC_ADDR_DEV
, reg
, tempreg
);
56 static void set_mmio_addr_reg(u32 nodeid
, u32 linkn
, u32 reg
, u32 index
,
57 u32 mmio_min
, u32 mmio_max
)
61 /* io range allocation. Limit */
62 tempreg
= (nodeid
& 0xf) | (linkn
<< 4) | (mmio_max
& 0xffffff00);
63 pci_write_config32(SOC_ADDR_DEV
, reg
+ 4, tempreg
);
64 tempreg
= 3 | (nodeid
& 0x30) | (mmio_min
& 0xffffff00);
65 pci_write_config32(SOC_ADDR_DEV
, reg
, tempreg
);
68 static void read_resources(struct device
*dev
)
73 * This MMCONF resource must be reserved in the PCI domain.
74 * It is not honored by the coreboot resource allocator if it is in
77 mmconf_resource(dev
, MMIO_CONF_BASE
);
79 /* NB IOAPIC2 resource */
80 res
= new_resource(dev
, IO_APIC2_ADDR
); /* IOAPIC2 */
81 res
->base
= IO_APIC2_ADDR
;
82 res
->size
= 0x00001000;
83 res
->flags
= IORESOURCE_MEM
| IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
86 static void set_resource(struct device
*dev
, struct resource
*res
, u32 nodeid
)
88 resource_t rbase
, rend
;
89 unsigned int reg
, link_num
;
92 /* Make certain the resource has actually been set */
93 if (!(res
->flags
& IORESOURCE_ASSIGNED
))
96 /* If I have already stored this resource don't worry about it */
97 if (res
->flags
& IORESOURCE_STORED
)
100 /* Only handle PCI memory and IO resources */
101 if (!(res
->flags
& (IORESOURCE_MEM
| IORESOURCE_IO
)))
104 /* Ensure I am actually looking at a resource of function 1 */
105 if ((res
->index
& 0xffff) < 0x1000)
108 /* Get the base address */
111 /* Get the limit (rounded up) */
112 rend
= resource_end(res
);
114 /* Get the register and link */
115 reg
= res
->index
& 0xfff; /* 4k */
116 link_num
= IOINDEX_LINK(res
->index
);
118 if (res
->flags
& IORESOURCE_IO
)
119 set_io_addr_reg(dev
, nodeid
, link_num
, reg
, rbase
>>8, rend
>>8);
120 else if (res
->flags
& IORESOURCE_MEM
)
121 set_mmio_addr_reg(nodeid
, link_num
, reg
,
122 (res
->index
>> 24), rbase
>> 8, rend
>> 8);
124 res
->flags
|= IORESOURCE_STORED
;
125 snprintf(buf
, sizeof(buf
), " <node %x link %x>",
127 report_resource_stored(dev
, res
, buf
);
131 * I tried to reuse the resource allocation code in set_resource()
132 * but it is too difficult to deal with the resource allocation magic.
135 static void create_vga_resource(struct device
*dev
)
139 /* find out which link the VGA card is connected,
140 * we only deal with the 'first' vga card */
141 for (link
= dev
->link_list
; link
; link
= link
->next
)
142 if (link
->bridge_ctrl
& PCI_BRIDGE_CTL_VGA
)
145 /* no VGA card installed */
149 printk(BIOS_DEBUG
, "VGA: %s has VGA device\n", dev_path(dev
));
150 /* Route A0000-BFFFF, IO 3B0-3BB 3C0-3DF */
151 pci_write_config32(SOC_ADDR_DEV
, D18F1_VGAEN
, VGA_ADDR_ENABLE
);
154 static void set_resources(struct device
*dev
)
157 struct resource
*res
;
160 /* do we need this? */
161 create_vga_resource(dev
);
163 /* Set each resource we have found */
164 for (res
= dev
->resource_list
; res
; res
= res
->next
)
165 set_resource(dev
, res
, 0);
167 for (bus
= dev
->link_list
; bus
; bus
= bus
->next
)
169 assign_resources(bus
);
172 static void northbridge_init(struct device
*dev
)
174 setup_ioapic((u8
*)IO_APIC2_ADDR
, CONFIG_MAX_CPUS
+1);
177 unsigned long acpi_fill_mcfg(unsigned long current
)
180 current
+= acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t
*)current
,
181 CONFIG_MMCONF_BASE_ADDRESS
,
184 CONFIG_MMCONF_BUS_NUMBER
);
189 static unsigned long acpi_fill_hest(acpi_hest_t
*hest
)
191 void *addr
, *current
;
193 /* Skip the HEST header. */
194 current
= (void *)(hest
+ 1);
196 addr
= agesawrapper_getlateinitptr(PICK_WHEA_MCE
);
198 current
+= acpi_create_hest_error_source(hest
, current
, 0,
199 (void *)((u32
)addr
+ 2), *(uint16_t *)addr
- 2);
201 addr
= agesawrapper_getlateinitptr(PICK_WHEA_CMC
);
203 current
+= acpi_create_hest_error_source(hest
, current
, 1,
204 (void *)((u32
)addr
+ 2), *(uint16_t *)addr
- 2);
206 return (unsigned long)current
;
209 static void northbridge_fill_ssdt_generator(struct device
*device
)
212 char pscope
[] = "\\_SB.PCI0";
214 acpigen_write_scope(pscope
);
215 msr
= rdmsr(TOP_MEM
);
216 acpigen_write_name_dword("TOM1", msr
.lo
);
217 msr
= rdmsr(TOP_MEM2
);
219 * Since XP only implements parts of ACPI 2.0, we can't use a qword
221 * See http://www.acpi.info/presentations/S01USMOBS169_OS%2520new.ppt
223 * Shift value right by 20 bit to make it fit into 32bit,
224 * giving us 1MB granularity and a limit of almost 4Exabyte of memory.
226 acpigen_write_name_dword("TOM2", (msr
.hi
<< 12) | msr
.lo
>> 20);
230 static unsigned long agesa_write_acpi_tables(struct device
*device
,
231 unsigned long current
,
243 current
= ALIGN(current
, 8);
244 hest
= (acpi_hest_t
*)current
;
245 acpi_write_hest(hest
, acpi_fill_hest
);
246 acpi_add_table(rsdp
, (void *)current
);
247 current
+= hest
->header
.length
;
250 if (CONFIG(ACPI_BERT
) && bert_errors_present()) {
251 /* Skip the table if no errors are present. ACPI driver reports
252 * a table with a 0-length region:
253 * BERT: [Firmware Bug]: table invalid.
257 bert_errors_region(&rgn
, &size
);
259 printk(BIOS_ERR
, "Error: Can't find BERT storage area\n");
261 current
= ALIGN(current
, 8);
262 bert
= (acpi_bert_t
*)current
;
263 acpi_write_bert(bert
, (uintptr_t)rgn
, size
);
264 acpi_add_table(rsdp
, (void *)current
);
265 current
+= bert
->header
.length
;
269 current
= ALIGN(current
, 8);
270 printk(BIOS_DEBUG
, "ACPI: * IVRS at %lx\n", current
);
271 ivrs
= agesawrapper_getlateinitptr(PICK_IVRS
);
273 memcpy((void *)current
, ivrs
, ivrs
->length
);
274 ivrs
= (acpi_header_t
*)current
;
275 current
+= ivrs
->length
;
276 acpi_add_table(rsdp
, ivrs
);
278 printk(BIOS_DEBUG
, " AGESA IVRS table NULL. Skipping.\n");
282 current
= ALIGN(current
, 8);
283 printk(BIOS_DEBUG
, "ACPI: * SRAT at %lx\n", current
);
284 srat
= (acpi_srat_t
*)agesawrapper_getlateinitptr(PICK_SRAT
);
286 memcpy((void *)current
, srat
, srat
->header
.length
);
287 srat
= (acpi_srat_t
*)current
;
288 current
+= srat
->header
.length
;
289 acpi_add_table(rsdp
, srat
);
291 printk(BIOS_DEBUG
, " AGESA SRAT table NULL. Skipping.\n");
295 current
= ALIGN(current
, 8);
296 printk(BIOS_DEBUG
, "ACPI: * SLIT at %lx\n", current
);
297 slit
= (acpi_slit_t
*)agesawrapper_getlateinitptr(PICK_SLIT
);
299 memcpy((void *)current
, slit
, slit
->header
.length
);
300 slit
= (acpi_slit_t
*)current
;
301 current
+= slit
->header
.length
;
302 acpi_add_table(rsdp
, slit
);
304 printk(BIOS_DEBUG
, " AGESA SLIT table NULL. Skipping.\n");
308 current
= ALIGN(current
, 16);
309 printk(BIOS_DEBUG
, "ACPI: * AGESA ALIB SSDT at %lx\n", current
);
310 alib
= (acpi_header_t
*)agesawrapper_getlateinitptr(PICK_ALIB
);
312 memcpy((void *)current
, alib
, alib
->length
);
313 alib
= (acpi_header_t
*)current
;
314 current
+= alib
->length
;
315 acpi_add_table(rsdp
, (void *)alib
);
317 printk(BIOS_DEBUG
, " AGESA ALIB SSDT table NULL."
321 current
= ALIGN(current
, 16);
322 printk(BIOS_DEBUG
, "ACPI: * SSDT at %lx\n", current
);
323 ssdt
= (acpi_header_t
*)agesawrapper_getlateinitptr(PICK_PSTATE
);
325 memcpy((void *)current
, ssdt
, ssdt
->length
);
326 ssdt
= (acpi_header_t
*)current
;
327 current
+= ssdt
->length
;
329 printk(BIOS_DEBUG
, " AGESA PState table NULL. Skipping.\n");
331 acpi_add_table(rsdp
, ssdt
);
333 printk(BIOS_DEBUG
, "ACPI: * SSDT for PState at %lx\n", current
);
337 static struct device_operations northbridge_operations
= {
338 .read_resources
= read_resources
,
339 .set_resources
= set_resources
,
340 .enable_resources
= pci_dev_enable_resources
,
341 .init
= northbridge_init
,
342 .acpi_fill_ssdt_generator
= northbridge_fill_ssdt_generator
,
343 .write_acpi_tables
= agesa_write_acpi_tables
,
348 static const unsigned short pci_device_ids
[] = {
349 PCI_DEVICE_ID_AMD_15H_MODEL_606F_NB_HT
,
350 PCI_DEVICE_ID_AMD_15H_MODEL_707F_NB_HT
,
353 static const struct pci_driver family15_northbridge __pci_driver
= {
354 .ops
= &northbridge_operations
,
355 .vendor
= PCI_VENDOR_ID_AMD
,
356 .devices
= pci_device_ids
,
360 * Enable VGA cycles. Set memory ranges of the FCH legacy devices (TPM, HPET,
361 * BIOS RAM, Watchdog Timer, IOAPIC and ACPI) as non-posted. Set remaining
362 * MMIO to posted. Route all I/O to the southbridge.
364 void amd_initcpuio(void)
366 uintptr_t topmem
= bsp_topmem();
367 uintptr_t base
, limit
;
369 /* Enable legacy video routing: D18F1xF4 VGA Enable */
370 pci_write_config32(SOC_ADDR_DEV
, D18F1_VGAEN
, VGA_ADDR_ENABLE
);
372 /* Non-posted: range(HPET-LAPIC) or 0xfed00000 through 0xfee00000-1 */
373 base
= (HPET_BASE_ADDRESS
>> 8) | MMIO_WE
| MMIO_RE
;
374 limit
= (ALIGN_DOWN(LOCAL_APIC_ADDR
- 1, 64 * KiB
) >> 8) | MMIO_NP
;
375 pci_write_config32(SOC_ADDR_DEV
, NB_MMIO_LIMIT_LO(0), limit
);
376 pci_write_config32(SOC_ADDR_DEV
, NB_MMIO_BASE_LO(0), base
);
378 /* Remaining PCI hole posted MMIO: TOM-HPET (TOM through 0xfed00000-1 */
379 base
= (topmem
>> 8) | MMIO_WE
| MMIO_RE
;
380 limit
= ALIGN_DOWN(HPET_BASE_ADDRESS
- 1, 64 * KiB
) >> 8;
381 pci_write_config32(SOC_ADDR_DEV
, NB_MMIO_LIMIT_LO(1), limit
);
382 pci_write_config32(SOC_ADDR_DEV
, NB_MMIO_BASE_LO(1), base
);
384 /* Route all I/O downstream */
385 base
= 0 | IO_WE
| IO_RE
;
386 limit
= ALIGN_DOWN(0xffff, 4 * KiB
);
387 pci_write_config32(SOC_ADDR_DEV
, NB_IO_LIMIT(0), limit
);
388 pci_write_config32(SOC_ADDR_DEV
, NB_IO_BASE(0), base
);
391 void fam15_finalize(void *chip_info
)
395 /* TODO: move IOAPIC code to dsdt.asl */
396 pci_write_config32(SOC_GNB_DEV
, NB_IOAPIC_INDEX
, 0);
397 pci_write_config32(SOC_GNB_DEV
, NB_IOAPIC_DATA
, 5);
399 /* disable No Snoop */
400 value
= pci_read_config32(SOC_HDA0_DEV
, HDA_DEV_CTRL_STATUS
);
401 value
&= ~HDA_NO_SNOOP_EN
;
402 pci_write_config32(SOC_HDA0_DEV
, HDA_DEV_CTRL_STATUS
, value
);
405 void domain_enable_resources(struct device
*dev
)
407 /* Must be called after PCI enumeration and resource allocation */
408 if (!romstage_handoff_is_resume())
409 do_agesawrapper(AMD_INIT_MID
, "amdinitmid");
412 void domain_set_resources(struct device
*dev
)
414 uint64_t uma_base
= get_uma_base();
415 uint32_t uma_size
= get_uma_size();
416 uint32_t mem_useable
= (uintptr_t)cbmem_top();
417 msr_t tom
= rdmsr(TOP_MEM
);
418 msr_t high_tom
= rdmsr(TOP_MEM2
);
419 uint64_t high_mem_useable
;
423 ram_resource(dev
, idx
++, 0, 0xa0000 / KiB
);
425 /* 0xa0000 -> 0xbffff: legacy VGA */
426 mmio_resource(dev
, idx
++, 0xa0000 / KiB
, 0x20000 / KiB
);
428 /* 0xc0000 -> 0xfffff: Option ROM */
429 reserved_ram_resource(dev
, idx
++, 0xc0000 / KiB
, 0x40000 / KiB
);
432 * 0x100000 (1MiB) -> low top useable RAM
433 * cbmem_top() accounts for low UMA and TSEG if they are used.
435 ram_resource(dev
, idx
++, (1 * MiB
) / KiB
,
436 (mem_useable
- (1 * MiB
)) / KiB
);
438 /* Low top useable RAM -> Low top RAM (bottom pci mmio hole) */
439 reserved_ram_resource(dev
, idx
++, mem_useable
/ KiB
,
440 (tom
.lo
- mem_useable
) / KiB
);
442 /* If there is memory above 4GiB */
444 /* 4GiB -> high top useable */
445 if (uma_base
>= (4ull * GiB
))
446 high_mem_useable
= uma_base
;
448 high_mem_useable
= ((uint64_t)high_tom
.lo
|
449 ((uint64_t)high_tom
.hi
<< 32));
451 ram_resource(dev
, idx
++, (4ull * GiB
) / KiB
,
452 ((high_mem_useable
- (4ull * GiB
)) / KiB
));
454 /* High top useable RAM -> high top RAM */
455 if (uma_base
>= (4ull * GiB
)) {
456 reserved_ram_resource(dev
, idx
++, uma_base
/ KiB
,
461 assign_resources(dev
->link_list
);
464 /*********************************************************************
465 * Change the vendor / device IDs to match the generic VBIOS header. *
466 *********************************************************************/
467 u32
map_oprom_vendev(u32 vendev
)
471 if ((vendev
>= 0x100298e0) && (vendev
<= 0x100298ef))
472 new_vendev
= 0x100298e0;
473 else if ((vendev
>= 0x10029870) && (vendev
<= 0x1002987f))
474 new_vendev
= 0x10029870;
478 if (vendev
!= new_vendev
)
479 printk(BIOS_NOTICE
, "Mapping PCI device %8x to %8x\n",
485 __weak
void set_board_env_params(GNB_ENV_CONFIGURATION
*params
) { }
487 void SetNbEnvParams(GNB_ENV_CONFIGURATION
*params
)
489 const struct device
*dev
= SOC_IOMMU_DEV
;
490 params
->IommuSupport
= dev
&& dev
->enabled
;
491 set_board_env_params(params
);
494 void SetNbMidParams(GNB_MID_CONFIGURATION
*params
)
496 /* 0=Primary and decode all VGA resources, 1=Secondary - decode none */
497 params
->iGpuVgaMode
= 0;
498 params
->GnbIoapicAddress
= IO_APIC2_ADDR
;