Re-read kernel storage management (7): icache support

Source: Internet
Author: User

Happy shrimp http://blog.csdn.net/lights_joy/lights@hb165.com this article applies to ADI bf561 DSPuclinux-2008r1-rc8 (transplanted to vdsp5) Visual DSP ++ 5.0 welcome reprint, but please keep the author information

1.1 icache support 1.1.1 register configuration InitializationIn the kernel, to support icache, you must first define a macro: # define config_bfin_icache 1 for icache Initialization Configuration in arch/Blackfin/kernel/cplb-nompu/cacheinit. c's bfin_icache_init function is complete: # If defined (config_bfin_icache) void bfin_icache_init (void) {unsigned long * Table = icplb_table; unsigned long CTRL; int I; for (I = 0; I <max_cplbs; I ++) {unsigned long ADDR = * Table ++; unsigned long data = * Table ++; If (ADDR = (unsigned long)-1) break; bfin_write 32 (icplb_addr0 + I * 4, ADDR); bfin_write32 (icplb_data0 + I * 4, data);} CTRL = bfin_read_imem_control (); CTRL | = IMC | enicplb; bfin_write_imem_control (CTRL); ssync () ;}# here, max_cplbs is defined as: # define max_cplbs (16*2) it is defined as 16*2 because it stores icplb_addr and icplb_data in an array, so * 2 is required. Icplb_table is a global variable defined as u_long icplb_table [max_cplbs + 1]. The value of the last cplb element is-1 (not necessarily the last element of the array ), used as the exit condition for the for loop in the preceding function. So where does the icplb_table value come from? The answer is cplbinit. C. 1.1.2 icplb_table generationIcplb_table generation is implemented by generate_cpl_tables. The following code deletes parts unrelated to icplb initialization: void _ init generate_cpl_tables (void) {I, j, process; u32 a_start, a_end, As, AE, as_1m; struct cplb_tab * t_ I = NULL; struct s_cplb cplb; cplb. init_ I .size = max_cplbs; cplb. init_ I .pos = 0; cplb. init_ I .tab = icplb_table; for (I = zero_p; I <array_size (cplb_data); ++ I) {If (! Cplb_data [I]. valid) continue; As = cplb_data [I]. start % size_4m; AE = cplb_data [I]. end % size_4m; if (as) a_start = cplb_data [I]. start + (size_4m-(AS); else a_start = cplb_data [I]. start; a_end = cplb_data [I]. end-AE; For (j = initial_t; j <= switch_t; j ++) {Switch (j) {Case initial_t: If (cplb_data [I]. ATTR & initial_t) {t_ I = & cplb. init_ I; T_d = & cplb. init_d; process = 1;} else process = 0; Break; default: Process = 0; break;} If (! Process) continue; If (cplb_data [I]. ATTR & I _cplb) _ fill_code_cplbtab (t_ I, I, a_start, a_end) ;}/ * close tables */close_cplbtab (& cplb. init_ I); cplb. init_ I .tab [cplb. init_ I .pos] =-1;} Here, cplb_data is an array of 10 elements defined in the file header. It details the attributes of each memory, such as size and type. When the program runs to the _ fill_code_cplbtab, the following parts will be filled in the array of icplb :{. start = l1_code_start ,. end = l1_code_start + l1_code_length ,. psize = size_4m ,. ATTR = initial_t | switch_t | I _cplb ,. I _conf = l1_imemory ,. d_conf = 0 ,. valid = 1 ,. name = "L1 I-memory ",},{. start = 0 ,. end = 0,/* dynamic */. psize = 0 ,. ATTR = initial_t | switch_t | I _cplb | d_cplb ,. I _conf = sdram_igeneric ,. d_conf = sdram_dgeneric ,. valid = 1 ,. Name = "kernel memory",}. The. End of the kernel memory block has been set to the end position of the SDRAM. 1.1.3 _ fill_code_cplbtabImplementation of this function:/* helper function */static void _ fill_code_cplbtab (struct cplb_tab * t, int I, u32 a_start, u32 a_end) {If (cplb_data [I]. psize) {fill_cplbtab (T, cplb_data [I]. start, cplb_data [I]. end, cplb_data [I]. psize, cplb_data [I]. I _conf); # If defined (config_bfin_icache) if (anomaly_05000263 & I = sdram_kern) {fill_cplbtab (T, cplb_data [I]. start, cplb_data [I]. end, size_4m, cplb_data [I]. I _conf);} els E # endif} else {fill_cplbtab (T, cplb_data [I]. start, a_start, size_1m, cplb_data [I]. I _conf); fill_cplbtab (T, a_start, a_end, size_4m, cplb_data [I]. I _conf); fill_cplbtab (T, a_end, cplb_data [I]. end, size_1m, cplb_data [I]. I _conf) ;}} static unsigned short _ initfill_cplbtab (struct cplb_tab * Table, unsigned long start, unsigned long end, unsigned long block_size, unsigned long cplb_data) {int I; Switch (Block_size) {Case size_4m: I = 3; break; Case size_1m: I = 2; break; Case size_4k: I = 1; break; Case size_1k: Default: I = 0; break;} cplb_data = (cplb_data &~ (3 <16) | (I <16); While (start <End) & (Table-> POS <Table-> size )) {table-> tab [Table-> POS ++] = start; If (lock_kernel_check (start, start + block_size) = in_kernel) table-> tab [Table-> POS ++] = cplb_data | cplb_lock | cplb_dirty; else table-> tab [Table-> POS ++] = cplb_data; start + = block_size;} return 0 ;} 1.1.3.1 L1 I-memoryWhen {. start = l1_code_start ,. end = l1_code_start + l1_code_length ,. psize = size_4m ,. ATTR = initial_t | switch_t | I _cplb ,. I _conf = l1_imemory ,. d_conf = 0 ,. valid = 1 ,. name = "L1 I-memory",}. When this block is passed in, it will directly call fill_cplbtab (T, cplb_data [I]. start, cplb_data [I]. end, cplb_data [I]. psize, cplb_data [I]. I _conf); from the fill_cplbtab function, we can see that the value of icplb_addr is l1_code_start, that is, 0xffa0 0000, and the value of icplb_data is 0x0003 0007. Value: The 16-bit and 17-bit values are 11, that is, the page size is 4 MB. 0th bits, that is, cplb_valid, is 1, indicating the valid cplb entry. 1st bits, that is, cplb_lock, is 1, which indicates cplb entry shocould not be replaced. The value 1 indicates the user mode read access permitted. 1.1.3.2 kernel memoryWhen {. start = 0 ,. end = 0,/* dynamic */. psize = 0 ,. ATTR = initial_t | switch_t | I _cplb | d_cplb ,. I _conf = sdram_igeneric ,. d_conf = sdram_dgeneric ,. valid = 1 ,. name = "kernel memory",}. When this block is passed in, it will call fill_cplbtab (T, cplb_data [I]. start, cplb_data [I]. end, size_4m, cplb_data [I]. I _conf); at this time, 15 SDRAM blocks will be generated, each of which is 4 m and will increase progressively from 0. In this case, their cplb_data value will be 0x0003 1205. The value indicates that the 16-bit and 17-bit values are 11, that is, the page size is 4 MB. 0th bits, that is, cplb_valid, is 1, indicating the valid cplb entry. 1st bits, that is, cplb_lock, 0, indicating that cplb entry can be replaced. The value 1 indicates the user mode read access permitted. 9th bits, that is, cplb_mem_lev, is 1, indicating determins line buffer, low priority. 12th bits, that is, cplb_l1_chbl, is 1, indicating cacherable in L1. 1.1.4 page feedObviously, at the time of initialization, icache cannot cover the entire bucket when the SDRAM is greater than 32 MB. At this time, the uClinux kernel will inevitably encounter an I-Fetch cplb Miss exception. The uClinux kernel handles this exception by _ cplb_mgr. This function is available in arch/Blackfin/kernel/cplb-nompu/cplbmgr. s, it will find a suitable block in the configuration list of the entire storage area, replace icache_data15 and icache_addr15, that is, it always replaces the latest page. Here, the configuration list of the entire storage area is saved in an array named ipdt_table. See its definition: u_long ipdt_table [max_switch_ I _cplbs + 1] pdt_attr; /** number of required instruction cplb switchtable entries * memsize/4 (we mostly install 4 m page size cplbs * approx 12 for smaller 1 MB page size cplbs for allignment purposes * 1 for L1 instruction memory * possibly 1 For L2 instruction memory * 1 for config_debug_hunt_for_zero */# define max_switch_ I _cplbs (Config_mem_size/4) + 12 + 1 + 1 + 1) * 2) This array also crossstores the values of icplb_addr and icplb_data, its Initialization is also completed by the generate_cpl_tables function, which is similar to the initialization of icplb_table.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.