- Bump the LinuxBIOS major version
[coreboot.git] / src / northbridge / intel / i855pm / northbridge.c
1 #include <console/console.h>
2 #include <arch/io.h>
3 #include <stdint.h>
4 #include <mem.h>
5 #include <part/sizeram.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <bitops.h>
11 #include "chip.h"
12
13 struct mem_range *sizeram(void)
14 {
15         static struct mem_range mem[4];
16         /* the units of tolm are 64 KB */
17         /* the units of drb16 are 64 MB */
18         uint16_t tolm, remapbase, remaplimit, drb16;
19         uint16_t tolm_r, remapbase_r, remaplimit_r;
20         uint8_t  drb;
21         int remap_high;
22         device_t dev;
23
24         dev = dev_find_slot(0, 0); // d0f0
25         if (!dev) {
26                 printk_err("Cannot find PCI: 0:0\n");
27                 return 0;
28         }
29         
30         /* Calculate and report the top of low memory and 
31          * any remapping.
32          */
33         /* Test if the remap memory high option is set */
34         remap_high = 0;
35 //        if(get_option(&remap_high, "remap_memory_high")){
36 //                remap_high = 0;
37 //        }
38         printk_debug("remap_high is %d\n", remap_high);
39         /* get out the value of the highest DRB. This tells the end of 
40          * physical memory. The units are ticks of 64 MB i.e. 1 means
41          * 64 MB. 
42          */
43         drb = pci_read_config8(dev, 0x67);
44         drb16 = (uint16_t)drb;
45         if(remap_high && (drb16 > 0x08)) {
46                 /* We only come here if we have at least 512MB of memory,
47                  * so it is safe to hard code tolm.
48                  * 0x2000 means 512MB 
49                  */
50
51                 tolm = 0x2000;
52                 /* i.e 0x40 * 0x40 is 0x1000 which is 4 GB */
53                 if(drb16 > 0x0040) {
54                         /* There is more than 4GB of memory put
55                          * the remap window at the end of ram.
56                          */
57                         remapbase = drb16;
58                         remaplimit = remapbase + 0x38;
59                 }
60                 else {
61                         remapbase = 0x0040;
62                         remaplimit = remapbase + (drb16-8);
63                 }
64         }
65         else {
66                 tolm = (uint16_t)((dev_root.resource[1].base >> 16)&0x0f800);
67                 if((tolm>>8) >= (drb16<<2)) {
68                         tolm = (drb16<<10);
69                         remapbase = 0x3ff;
70                         remaplimit = 0;
71                 }
72                 else {
73                         remapbase = drb16;
74                         remaplimit = remapbase + ((0x0040-(tolm>>10))-1);
75                 }
76         }
77         /* Write the ram configruation registers,
78          * preserving the reserved bits.
79          */
80         tolm_r = pci_read_config16(dev, 0xc4);
81         tolm |= (tolm_r & 0x7ff); 
82         pci_write_config16(dev, 0xc4, tolm);
83         remapbase_r = pci_read_config16(dev, 0xc6);
84         remapbase |= (remapbase_r & 0xfc00);
85         pci_write_config16(dev, 0xc6, remapbase);
86         remaplimit_r = pci_read_config16(dev, 0xc8);
87         remaplimit |= (remaplimit_r & 0xfc00);
88         pci_write_config16(dev, 0xc8, remaplimit);
89
90 #if 0
91     printk_debug("mem info tolm = %x, drb = %x, pci_memory_base = %x, remap = %x-%x\n",tolm,drb,pci_memory_base,remapbase,remaplimit);
92 #endif
93         
94         mem[0].basek = 0;
95         mem[0].sizek = 640;
96         mem[1].basek = 768;
97         /* Convert size in 64K bytes to size in K bytes */
98         mem[1].sizek = (tolm << 6) - mem[1].basek;
99         mem[2].basek = 0;
100         mem[2].sizek = 0;
101         if ((drb << 16) > (tolm << 6)) {
102                 /* We don't need to consider the remap window
103                  * here because we put it immediately after the
104                  * rest of ram.
105                  * All we must do is calculate the amount
106                  * of unused memory and report it at 4GB.
107                  */
108                 mem[2].basek = 4096*1024;
109                 mem[2].sizek = (drb << 16) - (tolm << 6);
110         }
111         mem[3].basek = 0;
112         mem[3].sizek = 0;
113         
114         return mem;
115 }
116
117 struct chip_operations northbridge_intel_i855pm_control = {
118         .name      = "intel i855pm Northbridge",
119 };